排序演算法之(7) 堆排序

2021-08-20 03:16:23 字數 1185 閱讀 1192

堆排序(heap sort)就是利用堆(假設利用大頂堆)進行排序的方法。它的基本思想是,將待排序的序列構造成乙個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走(其實就是將其與堆陣列的末尾元素交換,此時末尾元素就是最大值),然後將剩餘的n-1個序列重新構造成乙個堆,這樣就會得到n個元素中的次小值。如此反覆執行,便能得到乙個有序序列了。

堆排序真的是乙個好東西,不管是待排序序列有序無序,時間複雜度都基本一樣。

注:這裡堆是一種資料結構,而非記憶體的那個堆。可以參考完全二叉樹,可以表示成乙個陣列。

//堆排序

/*這個堆是資料結構堆,不是記憶體malloc相關的那個堆--我曾經理解錯n久

根節點比孩子節點都大的叫大頂堆(包括子樹的根),比孩子節點小的叫小頂堆

從小到大排序用的是大頂堆,所以要先構造這種堆,然後把這個根的最大元素交換到最尾巴去

每次拿走乙個最大元素,待排序的佇列就慢慢變短

主要步驟1,初始化構造這種大頂堆,把堆頂最大的數放到最尾巴,數列長度減少1,再次構建大頂堆

2,這時候只有堆頂元素不滿足大頂堆,那麼其實只要從堆頂元素開始慢慢微調而已,沒必要再完全重新建堆,想要也可以,不過很浪費時間

理解起來確實很難,涉及到完全二叉樹

孩子節點i的爸爸是i/2,爸爸節點的兒子是2i和2i+1。

第一次初始化之後充分利用子樹已經是大頂堆

*///輔助函式:交換兩個變數

void swap(int*a,int*p)

void adjust(int* arr,int len,int index)

if(rightarr[max])

//如果父親節點不是最大

if(max!=index)

}//主要排序部分

void heapsort(int* arr,int len)

swap(&arr[0],&arr[len-1]);

//第二次之後,只需要從根節點從上到下調整,遇到沒發生交換的直接可以退出迴圈了

//微調得到大頂堆(因為只有堆頂不滿足而已)

int j = len -1; //去掉尾節點後的陣列長度

//把最大值交換到最後

for(j;j>0;j--)

}

排序演算法之(7) 堆排序

堆排序主要是利用了堆的性質,對於大頂堆 堆中的每個節點的值都不小於它的孩子節點的值,詳細可參考我的另一篇部落格那麼大頂堆的堆頂元素就是當前堆中所有元素中最大的。利用這個性質,進行如下操作,則可以得到乙個有序序列 將待排序的n個元素乙個乙個插入堆中,那麼此時堆頂元素就是所有元素中最大的 將堆頂元素取出...

排序演算法之(7) 堆排序

堆排序主要是利用了堆的性質。對於大頂堆 堆中的每乙個節點的值都不小於它的孩子節點的值,具體可參考我的還有一篇部落格那麼大頂堆的堆頂元素就是當前堆中全部元素中最大的。利用這個性質。進行例如以下操作,則能夠得到乙個有序序列 將待排序的n個元素乙個乙個插入堆中,那麼此時堆頂元素就是全部元素中最大的 將堆頂...

排序演算法之(7) 堆排序

堆排序主要是利用了堆的性質。對於大頂堆 堆中的每乙個節點的值都不小於它的孩子節點的值,具體可參考我的還有一篇部落格那麼大頂堆的堆頂元素就是當前堆中全部元素中最大的。利用這個性質。進行例如以下操作,則能夠得到乙個有序序列 將待排序的n個元素乙個乙個插入堆中,那麼此時堆頂元素就是全部元素中最大的 將堆頂...