在資料結構之堆的基本操作這篇部落格當中提到過乙個堆排序。就是將乙個堆的元素刪除完畢過後,此時的陣列內部就是乙個有序的序列。
堆與排序
堆是乙個完全二叉樹,堆的任意乙個節點都是以這個節點為根節點的樹中的最值(最大或最小值)這樣子的話,每乙個堆的堆頂元素都是這個堆的最值。那麼依次刪除乙個堆的堆頂,最後就能夠得到乙個有序的序列。
而堆排序就是利用了堆的這個性質來進行排序的過程。
在進行徹底的刪除完畢後,剩下的序列就是2 3 4 5 6 9這就就是乙個有序的序列!!
所以堆排序的主要思路就是兩個:
將陣列構建成乙個堆
依次刪除這個堆
void adjustdown(int array, int
parent, int
size) // 下沉式調整
if (array[parent] < array[child]) else
} // end while (1)
return;
}void heapcreate(int array, int
size)
intparent = (size - 1 - 1) / 2;
for (; parent >= 0; parent--)
return;
}void heapsort(int array, int
size)
heapcreate(array, size); // 建立堆
int i = 0;
for (; i < size; ++i)
return;
}
堆的操作最核心的就是下沉與上浮,由於堆的刪除是進行下沉操作的,所以這裡在構建堆的時候也使用下沉的方式來構建堆。構建堆的時候先找到第乙個父節點,可以根據最後乙個葉子節點來計算出其父節點,接下來就是依次遍歷,依次下沉的過程,最終構建乙個堆。
刪除的時候就是乙個簡單的堆頂刪除,與最後乙個葉子節點交換,接著下沉堆頂的葉子節點即可。
切記!!!
這裡要注意的是,由於每次刪除後,堆內元素減少,同時在下沉傳參的時候一定要注意好傳什麼引數進去,以免對不屬於堆的元素進行操作。
堆排序的時間複雜度是 o(n*logn),空間複雜度是 o(1)由於這裡我們在原有的陣列內部建立堆,並沒有建立新的空間,所以是o(1),排序穩定性:不穩定。
排序演算法 堆排序
1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...
排序演算法 堆排序
花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...
排序演算法 堆排序
由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...