堆排序演算法
堆是乙個陣列,他可以被看成是乙個近似的完全二叉樹,除了最底層之外,該數是完全充滿的。一般的,給定一顆二叉樹的乙個節點,可以很快的算出它的父、左子、右子節點。
parent(i)=i/2
left(i)=i*2
right(i)=i*2+1
最大堆是指的除了根節點外的所有節點,都滿足a(parent(i))>=a(i)。乙個堆的高度也就是o(lgn)。乙個堆排序演算法的基本過程包括:維護最大堆max-heapify,時間複雜度為o(lgn); 構造乙個最大堆build-max-heap;原址排序堆過程heapsort,時間複雜度為o(nlgn)。
維護最大堆
max-heapify用來維護最大的堆,它的輸入是乙個沒有建立好的堆以及乙個將要維護的位置。假定在呼叫它時,該即將維護的位置的左右子樹都已經維護好了,但是該節點有可能小於左右子樹。因此,需要將它和左右子樹的最大值變換順序,此時,子樹也有可能不滿足最大堆的條件,依次呼叫這個過程,使得該節點的子樹能滿足最大堆的要求。
max-heapify(i)
(maxvalue, maxind)=max(right(i),value(i),left(i))
if maxvalue > value(i)
swap(maxvalue,value(i))
max-heapify(maxind)
建堆 build-max-heap:維護最大堆時,假定該即將維護的位置的左右子樹都已經維護好了。為了達到這乙個假定的條件,可以對初始堆進行從底往上進行呼叫max-heapify(i)。假定堆的長度為length,則:
for i = length/2 : -1 : 1
max-heapify(i)
堆排序演算法
通過以上兩步,可以建立乙個最大堆。堆的最大元素總是在a(1)中。因此,將a(1)取出,並將a(end)放到a(1)所在的位置上,然後對位置1進行維護最大堆,過程如下:
heapsort
for i = length : -1:2
swap a(1) with a(length)
length–
max-heapify(1)
void swap(int
*pna, int
*pnb)
void max_heapify(int num , int thisindex,int
size)
} // 該數和最小者進行比較,
if (num[thisindex] < num[minindex])
else
}// while
}void build_max_heap(int num ,int
size) }
void heapsort(int num ,int
size)
}
排序演算法 堆排序
1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...
排序演算法 堆排序
花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...
排序演算法 堆排序
由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...