【問題描述】:關於排序的問題,我們之前見過氣泡排序,其時間複雜度為o(n^2),效率很低,那有沒有高效一點的排序方法?我們就要說到堆排序了,本部落格中主要討論堆排序的實現,以及其時間複雜度分析。
【解題思路】:我們知道如果乙個二叉樹滿足堆的特性,那麼堆頂元素則一定是整個堆中最大或最小的元素(這取決於大堆或小堆),那如果我們需要將一組資料進行公升序排序,那麼我們將這組元素拿來建立乙個大堆,堆頂元素為整個陣列中最大元素。然後利用堆刪除的思想,將堆中最後乙個節點的元素與堆頂元素進行交換,現在我們就將這個最大的元素放到了最後乙個節點的位置上,接下來將新置換過去的堆頂元素調整至合適位置,再將堆中有效節點個數減一,現在堆頂元素就是整個陣列中次大的那個了,同理進行接下來的步驟,最終我們就會得到乙個按公升序排好序的堆了。
接下來以公升序排序為例,來看一下具體的**實現:
堆調整(大堆):
void swap(hpdatatype* pleft, hpdatatype* pright)
void heapadjust(int* array, int size, int parent)
}}
堆排序:
void heapsort(int* array, int size)
}
如果是要降序排序的話,則在堆調整時取小的節點。
時間複雜度分析:
先看一下建立堆的時間複雜度:
需要調整的節點個數:n/2個。根據二叉樹的性質我們可知終端節點數n0=度為2節點數n2+1,將常數1忽略掉可得:n0=n2。所有的n2都需要調整,所以需要調整的節點個數為總節點數n/2。
調整一次的時間複雜度:logn。完全二叉樹共有n個節點,高度為log(n+1),化簡到logn,調整一次的時間複雜度最差情況需要調整二叉樹的高度次,所以調整一次的時間複雜度為logn。
所以建立堆的時間複雜度為:n/2logn,化簡到nlogn。
然後再來看一下排序時的時間複雜度:排序時我們採用的是刪除堆的思想,而刪除堆的時間複雜度也是nlogn。
所以堆排序的時間複雜度為:2nlogn,化簡到nlogn。
堆排序及其時間空間複雜度分析
堆排序 乙個建立堆的函式,乙個排序的函式 heap初始建堆 大根堆 取得左右孩子中最大的結點,用其和根節點交換,然後以此孩子結點繼續建堆 heapsort 堆排序,先從非葉節點到跟進行迴圈建堆,交換根節點和最後乙個元素的位置,在迴圈建堆,時間複雜度 主要在於初始化建堆和後來交換後迴圈建堆的過程。迴圈...
堆排序重建堆的時間複雜度 堆排序及其時間複雜度
堆排序 這裡構建陣列過程只是做乙個簡單的示例,複雜情況暫不考慮 接受鍵盤輸入n個數,構建陣列 int setuparr int n scanf d n int arr int malloc sizeof int n if arr for int i 0 i n i scanf d arr i ret...
資料結構與演算法 演算法及其時間複雜度
寒假開始自學資料結構與演算法,到現在很多東西因為上網課的原因都沒時間再回過頭複習一遍,以致現在很多內容都不清晰了,今天有空就把時間複雜度這一部分進行整理。時間複雜度 評估執行程式所需的時間。可以估算出程式對處理器的使用程度。空間複雜度 評估執行程式所需的儲存空間。可以估算出程式對計算機記憶體的使用程...