1. 程式人生 > 其它 >堆排序--c++實現

堆排序--c++實現

大頂堆與小頂堆的概念

大頂堆:每個節點的值都大於或等於其他左右孩子節點的值。

小頂堆:每個節點的值都小於或等於其他左右孩子節點的值。

堆排序過程:

  1. 先將n個元素的無序序列,構建成大頂堆。
  2. 將根節點與最後一個元素交換位置
  3. 交換之後可能不再滿足大頂堆的條件,所以需要將剩下的n-1個元素重新構建成大頂堆
    • 交換過程:
      • )先找到最後一個非葉子節點,最後一個非葉子節點為:(長度/2-1),然後比較該節點值與他的子數值,如果該節點小於其他左右子樹的值就交換。
      • )繼續找到下一個非葉子節點,當前座標-1的位置,在進行比較該節點的值與其左右子樹節點的值是否符合大頂堆,不符合則交換。
  4. 重複第二步,第三步直到整個陣列排序完成。

堆排序的規律

升序---使用大頂堆

降序---使用小頂堆

程式碼實現:

#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;
}

測試結果: