堆排序(heapsort)是指利用堆積樹(堆)這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即a[parent[i]] >= a[i]。在陣列的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂。在分析堆排序演算法之前,首先要分析堆這種資料結構,在堆中二叉堆又是最為經典的一種堆的實現方式,所以下面分析二叉堆得定義。
二叉堆其實可以看成一棵二叉樹,但這個二叉樹滿足一些要求。以大頂堆為例,根節點的值要比孩子節點的值大,同樣孩子節點作為根節點所構成的子樹同樣滿足根節點的值大於孩子節點的值。並且這個二叉樹是一顆完全二叉樹。
雖然從圖中看到的二叉堆是樹形結構,但是由於這個二叉堆是個完全二叉樹,如果給每個節點編個號,就能夠很容易的用陣列來儲存乙個二叉堆。假設乙個節點的編號是x,那麼這個節點的左孩子的編號是2*x,右孩子的編號是2*x+1,父節點的編號是x/2。(這裡起始編號是1)
要往二叉堆裡插入乙個新的節點時,並不是簡單的在末尾新增就行了,因為這麼草率的話就不能使得插入新節點後還是滿足二叉堆的性質。為了插入正確,需要進行shift up操作,即上浮操作。shift up操作的流程下面將舉例說明。
假設我們要往這個二叉大頂堆裡插入乙個值為52的新節點。初始狀態如下圖所示,其中陣列的0號索引不儲存任何節點資訊。
此時52這個節點比它的父節點還要大,違背了大頂堆的性質。怎麼讓52到達合適的位置呢?其實在插入52之前,整個堆是滿足大頂堆性質的,當插入52的時候才出現了不滿足大頂堆性質的問題。因此只需要將52這個節點不斷地和它的父節點比大小,如果比父節點大,就和父節點交換就行了。並且維護乙個變數來記錄陣列的大小。
要從二叉堆裡面刪除乙個節點時,同樣不能簡單的將第乙個節點刪掉,因為那樣會導致二叉堆不滿足堆的性質。為了刪除正確,需要進行shift down操作,即下沉操作。shift down操作的流程下面將舉例說明。
假設我們要刪除兒叉大頂堆中最大的節點,也就是根節點。初始狀態如下圖所示,其中陣列的0號索引不儲存任何節點資訊。
當然這個時候需要把根節點刪掉。刪除的話其實就是把根結點和最後乙個孩子節點進行交換,然後用乙個變數count來維護陣列的大小,沒刪除乙個節點count就-1,也就相當於將節點給刪掉了。
但是這樣做還不夠,從上圖可以看出此時的根節點並不比孩子節點大,因此接下來就要對根節點進行shift down操作。shift down操作主要思路是將當前節點和它的孩子節點們進行比較,如果當前節點的值比孩子節點的最大值大,那麼結束shift down操作,否則就和最大的孩子節點進行交換,以此類推。在這裡16比max(52,30)小,所以16和52進行交換。
然後16比max(28,41)小,所以16和41進行交換
此時16比15大,結束shift down操作。可以看到此時的二叉堆依然是乙個二叉大頂堆。
templateclass
maxheap
~maxheap()
int size()
bool isempty()
//插入
void insert(item item)
m_pdata[++m_size] = item;
shiftup(m_size);
}//刪除
item extractmax()
private:
void shiftup(int
index)
}void shiftdown(int
index)
else
break;
}else
if (index * 2
<= m_size)
else
break;
}else
break;}}
private:
item* m_pdata; //陣列
int m_size; //當前二叉堆的size
int m_capacity; //容量,size<=capacity
};
演算法鋪子之排序 快速排序(一)
快速排序是20世紀世界上最偉大的演算法之一,顧名思義,這個演算法能很快的對資料進行排序。而且在很多庫的底層 中也經常使用快速排序來實現排序的功能,比如jdk,stl等。以公升序為例。首先會找乙個元素v作為基準,然後將整個待排序序列parttion成3個區域a,b和c。其中a區域為全部比v小的元素,b...
演算法鋪子之排序 插入排序
插入排序和選擇排序同樣是一種較為常見且容易實現的o n 2 級別的排序演算法,但插入排序的效率和待排序資料的有序程度有關係,待排序資料的有序程度越高,插入排序的效率也就越高,甚至有時候能比o nlogn 級別的排序演算法的效率還要高。所以插入排序也通常會成為其他排序演算法的子過程。插入排序的思路和我...
排序演算法之堆排序
前言 今天我來介紹下堆排序,在寫堆排序 之前,我們要知道堆的概念!堆的定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 當然,這是小根堆,大根堆則換成 號。k i 相當於二叉樹的非葉子結點,k 2i 則...