堆排序--c++實現
阿新 • • 發佈:2021-05-11
大頂堆與小頂堆的概念
大頂堆:每個節點的值都大於或等於其他左右孩子節點的值。
小頂堆:每個節點的值都小於或等於其他左右孩子節點的值。
堆排序過程:
- 先將n個元素的無序序列,構建成大頂堆。
- 將根節點與最後一個元素交換位置
- 交換之後可能不再滿足大頂堆的條件,所以需要將剩下的n-1個元素重新構建成大頂堆
- 交換過程:
- )先找到最後一個非葉子節點,最後一個非葉子節點為:(長度/2-1),然後比較該節點值與他的子數值,如果該節點小於其他左右子樹的值就交換。
- )繼續找到下一個非葉子節點,當前座標-1的位置,在進行比較該節點的值與其左右子樹節點的值是否符合大頂堆,不符合則交換。
- 交換過程:
- 重複第二步,第三步直到整個陣列排序完成。
堆排序的規律
升序---使用大頂堆
降序---使用小頂堆
程式碼實現:
#pragma once #include <vector> using namespace std; void buildBigHeap(vector<int>&arr,int len,int index) { int left = 2 * index + 1; int right = 2 * index + 2; int maxIndex = index; if (left<len && arr[left]>arr[maxIndex]) maxIndex = left; if (right<len && arr[right]>arr[maxIndex])maxIndex = right; if (maxIndex != index) { swap(arr[maxIndex], arr[index]); buildBigHeap(arr, len, maxIndex); } } void heapSort(vector<int>& arr) { int size = arr.size(); //建立大根堆 for (int i = size / 2 - 1; i >= 1; i--) { buildBigHeap(arr, size, i); } //每次將根節點放到最後面,調整大根堆 for (int i = size - 1; i >= 1; i--) { swap(arr[0], arr[i]); buildBigHeap(arr, i, 0); } }
舉例測試:
int main() { vector<int>arr = { 6,5,7,9,3,4,0 }; cout << "排序前 "; for (int i = 0; i < arr.size(); i++) { cout <<arr[i] << " "; } cout << endl; heapSort(arr); cout << "排序前 "; for (int i = 0; i < arr.size(); i++) { cout <<arr[i] << " "; } return 0; }