反覆將大根堆的根與最後乙個結點交換,堆的大小減一,對根結點執行max_heapify維護堆的性質。
最終 a 陣列按公升序排列。
void heapsort()
}
6.4-1 說明 heapsort 在陣列 a = <5,13,2,25,7,17,20,8,4> 上的操作過程。![](https://pic.w3help.cc/949/1a4ca174111ec94169e47c72b7dd7.jpeg)
6.4-2 討論在使用如下迴圈不變式時,heapsort的正確性:
在每次for迴圈的迭代開始時,
子陣列a[1..i]是乙個包含了a[1..n]中的i個最小元素的最大堆;
而子陣列a[i+1..n]包含了已排序的a[1..n]中的n-i個最大元素。
初始化:在第一輪迭代之前,i = n,a[1..n]是包含前n個最小元素的最大堆;子陣列a[n+1..n]中沒有元素,即已排好序的0個最大元素。
保持:將a[1..i]個包含了a[1..n]中的最小i個元素中的最大元素移動到 a[i],由於 a[i]>=a[1..i-1],a[i]<=a[i+1..n],因此a[i..n]包含了已排序的a[1..n]中的n-i+1個最大元素。
對新的根結點執行max_heapify保持堆的性質,因此a[1..i-1]是乙個包含了a[1..n]中的i-1個最小元素的最大堆。
for 迴圈中遞減i,為下一次迭代重新建立了迴圈不變式。
終止:過程終止時,i=1。根據迴圈不變式,我們知道a[2..n]包含了已排序的n-1個最大元素。a[1]是a[1..n]中最小的元素。
因此a[1..n]是乙個已排好序的陣列。
6.4-3 對乙個其所有n個元素已按遞增序排列的陣列a,堆排序的執行時間是多少?若a的元素成降序呢?
當a公升序排列時:
執行build_max_heap建堆,時間 o(n)。 迴圈呼叫max_heapify維護堆,時間 o(n)*o(logn),總複雜度o(nlogn)。
當a降序排列時,與公升序排列相同。
6.4-4 證明:堆排序的最壞情況執行時間為ω(nlogn)。
引用別人家的證明:
*6.4-5 證明:在所有元素都不相同時,堆排序的最佳執行時間是ω(nlogn)。
《演算法導論》筆記 第6章 堆排序
第6章 堆排序 本章主要介紹了堆的基本知識和幾個基本操作過程 堆 二叉 堆資料結構是一種陣列物件,它可以被看作是一棵完全二叉樹。heap size a 即堆的大小是已知的,樹的根結點是a 1 某個i結點,它的父結點parent i 為,左兒子left i 和右兒子right i 的下標可以簡單地計算...
《演算法導論》 第6章堆排序
include include using namespace std 定義結構體,其中包含陣列長alength,堆長heap size。struct dui 返回堆中元素i的父結點的下標 i 2向下取整,即i進行左移一位操作。int parent int i 返回堆中元素i的左孩子的下標 i 2 ...
演算法導論第6章 堆排序
本章開始介紹了堆的基本概念,然後引入最大堆和最小堆的概念。全章採用最大堆來介紹堆的操作,兩個重要的操作是調整最大堆和建立最大堆,接著著兩個操作引進了堆排序,最後介紹了採用堆實現優先順序佇列。1 堆 堆給人的感覺是乙個二叉樹,但是其本質是一種陣列物件,因為對堆進行操作的時候將堆視為一顆完全二叉樹,樹種...