堆排序是乙個非常出色的演算法,在時間複雜度是o(nlog(n))
,在空間上是就地排序。
堆,又叫二叉堆,被是視為完全二叉樹。堆可以分為兩種,最大堆和最小堆,最大堆的意思是,每乙個節點(除根節點以外)的值一定小於或等於它的父節點的值。最小堆的意思是,每個節點(除根節點外)的值一定小於或等於他的父節點的值。最大堆中的最大值一定位於它的根節點,而最小堆的最小值也一定位於它的根節點。
我們是通過乙個陣列來儲存乙個堆的。下面的三個函式用來獲取乙個節點的父節點、左子節點和右子節點的位置
static
int getparentindex(int i)
static
int getleftindex(int i)
static
int getrightindex(int i)
heapsize是堆的邏輯長度,小於等於陣列的長度。
堆排序由下面三個子過程組成
maxheapify(int array, int i)
,它的作用是保持堆的性質,執行完該函式後,以i節點為根的子樹將成為乙個堆,滿足堆的性質
buildmaxheap(int array)
,建立乙個最大堆。執行完該函式後,array陣列將成為乙個邏輯堆。
heapsort(int array)
,堆排序函式。執行完該函式後,array陣列將被由小到大排序完畢
先來看看maxheapify
函式
static
void maxheapify(int array, int i)
if (largest != i)
}
函式的大意是:比較i節點、它的左孩子節點和右孩子節點的數值,將最大值所在的位置賦值給largest,然後如果largest!=i,則交換i和largest位置的值,即將這三個之中的最大值留在根節點,並遞迴呼叫maxheapify(array, largest)
直到以i為根的子樹成為乙個最大堆。
下面是buildmaxheap
函式
static
int heapsize = 0;
static
void buildmaxheap(int array)
}
這個過程會一步一步地將較大的值往父節點上移動,直到形成乙個最大堆。
下面是最後的heapsort
的**
static
void heapsort(int array)
}
首先,它會呼叫heapsort
來建立乙個最大堆。最大堆中最大的元素一定在根節點,所以,每次迴圈都把根節點中的元素和當前迴圈變數所對應的值交換,並將堆的邏輯長度減一,再通過maxheapify(array, 0)
來將現有的元素組織成乙個最大堆。最後排序完成。
下面是main函式中來呼叫heapsort
static
void main(string args)
; heapsort(array);
}
下面是完成的**
class program
; heapsort(array);
printarray(array);
}static
void heapsort(int array)
}static
void buildmaxheap(int array)
}static
void maxheapify(int array, int i)
if (largest != i)
}static
int getparentindex(int i)
static
int getleftindex(int i)
static
int getrightindex(int i)
static
void printarray(int array)
console.writeline();
}}
排序演算法 堆排序
1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...
排序演算法 堆排序
花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...
排序演算法 堆排序
由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...