新手講排序 堆排序 和 認識二叉堆

2022-08-05 07:36:11 字數 1727 閱讀 5547

二叉堆是完全二叉樹或者是近似完全二叉樹

二叉堆滿足的二個特性:

1.父節點的鍵值總是大於或等於(小於或等於)任何乙個子節點的鍵值

2.每個節點的左子樹和右子樹都是乙個二叉堆(都是最大堆或者是最小堆)

當父節點的鍵值總是大於或等於任何乙個子節點的鍵值時為最大堆,總是小於或等於任何乙個子節點的鍵值時為最小堆

堆的儲存:

堆的儲存一般是用陣列來儲存,根據完全二叉樹的儲存結構,乙個節點的父節點為(i-1)/2,乙個節點的左孩子為2*i+1,右孩子為2*i+2

堆的建立插入和刪除:

堆得插入:

每次插入都是將新資料放在陣列的最後,可以發現從這個新資料的父節點到根節點必然為乙個有序的數列。

void minheapaddnumber(int *a,int n,int

nnum)

}

堆的刪除:

//節點從i開始,節點總數n 

//刪除的時候每次刪除最上面那乙個節點(根節點)

//然後將最後乙個元素放在根節點上

//然後根節點一次與他的左右節點進行比較,找出乙個最小的,進行交換,

//知道到最後乙個節點或者中間 沒有元素可以交換

void minheapfixdown(int a,int i,int n)

if(a[j]>=temp) break;

//這裡很奇妙,將較小的孩子節點往上移動,

//因為上面是和temp進行的比較,所以a[i]=temp這一步可以省略

//只在最後出現一次

a[i]=a[j];

i=j;

j=2*i+1;

} a[i]=temp;

}void minheapdeletenumber(int *a,int n)

堆化陣列:

有了堆的插入和刪除函式,在考慮將乙個資料進行堆化操作。

例子:可以看出堆化資料的時候,從最後乙個非葉子節點開始,那也就是2*i+1=n-1(索引),或者2*i+2=n-1,所以可以得到 i=n/2-1;即為最後乙個非葉子結點

可以得到**:

//

建立最小堆

void makeminheap(int *a,int

n)}

以上就是堆的基本操作。下面來講堆排序

堆排序:

首先可以得到堆建好之後,第0個元素肯定是最小的,取出這個資料在執行下堆的刪除,這樣第0個元素又是最小的,重複上述步驟,知道堆中只剩乙個元素直接取出。

由於堆是用陣列模擬的,故堆化後,第一次將a[0] 與 a[n-1]交換,再對a[0,n-2]進行恢復,重複直到a[0]與a[1]交換,由於每次都是將最小的資料併入到後面的區間,所以操作完成後整個陣列就有序了。所以使用最小堆排序後是遞減陣列,要得到遞增資料,可以使用最大堆

//

堆排序void minheapsorttodescendarray(int *a,int

n)}

堆排序的時間複雜度:

由於每次重新恢復堆的時間複雜度是o(logn),共n-1次重新恢復堆操作,再加上前面建立堆時n/2次向下調整,每一次時間複雜度也是o(logn);

所以堆排序的時間複雜度是o(nlogn);

二叉堆和堆排序

二叉 堆是乙個陣列,它可以近似看作完全二叉樹。樹上的每乙個節點對應陣列中的乙個元素。除了最底層,該樹是完全充滿的,而且是從左向右填充。根據節點下標可以求出對應的子樹和雙親 parent i return i 2 i表示陣列中的第幾個元素,i 2 表示取整數 left i return 2 i rig...

二叉堆和堆排序的python實現

二叉堆本質上是一種完全二叉數 二叉堆建立 根據原陣列,然後從最後乙個非葉子節點開始,依次下沉,得到最後序列 二叉堆操作 圖比較麻煩就不畫了,可以參考這篇文章 二叉堆 1.二叉堆實現 儲存方式 利用陣列順序儲存 定位方法 利用陣列下標進行定位 父節點parent,左子樹 2 parent 1,右子樹 ...

排序二 堆排序

子結點的鍵值或索引總是小於 或者大於 它的父節點。堆通過一維陣列實現。在起始陣列為 0 的情形中 父節點i的左子節點在位置 2 i 1 父節點i的右子節點在位置 2 i 2 子節點i的父節點在位置 floor i 1 2 堆中的最大值總是位於根節點。堆中定義以下幾種操作 1 最大堆調整 max he...