基礎排序算法之堆排序

基本思想(默認升序):利用二叉樹中的最大堆,每一個結點都比其所有子結點的值大的特點,第一個結點的值最大,將第一個結點與最後一個結點交換,這樣最後一個結點肯定是最大的,然後對前n-1個元素 重新進行構造最大堆,再重複上述步驟;

平均時間複雜度: O(N log N);

demo:

#include<iostream>
#include<vector>
using namespace std;
//堆排序  時間複雜度 O(n* log n)
/*
	藉由二叉樹的最大堆(最小堆)實現,對於升序,先將數組 排成 最大堆,降序則派成最小堆;
	然後, 每次將二叉樹第一個元素與最後一個元素交換,這樣最後一個元素就是最大(最小)值,
	然後重新將前面N-1個元素構建成最大堆;
	重複操作,將第一個元素與倒數第N個元素交換,在將前N-1個元素 構建成最大堆;
*/
#define RADIX 10
void my_swap(int& first, int& second)
{
	int tmp = first;
	first = second;
	second = tmp;
}
//構建堆
void BuildHeap(vector<int>&vec, int index, int last)
{
	int parent, child;
	int val = vec[index];//處理的元素
	for (parent = index; parent*2+1 <= last; parent = child)
	{
		child = parent * 2 + 1;
		//child指向左右結點中的較大者
		if (child < last && vec[child] < vec[child + 1])
			child++;

		if (val >= vec[child]) break; //找到位置
		else vec[parent] = vec[child];//繼續向下
	}
	vec[parent] = val;
}

void HeapSort(vector<int>&vec)
{
	if (vec.size()<2) return;
	int last = vec.size()-1;
	//從最後一個結點的父節點開始,構建最大堆,根結點是 index=0
	for (int i = (last-1 )/2; i >= 0; i--)
	{
		BuildHeap(vec, i, last);
		/*cout << "heap:" << endl;
		for (int j=i; j <=last; j++)
			cout << vec[j] << " ";
		cout << endl;*/
	}
	
	while (last >= 0)
	{
		my_swap(vec[0], vec[last--]);
		BuildHeap(vec, 0, last);
	}
}
int main()
{
	vector<int> arr = { 12,5,9,34,3,97,63,23,53,87,120,999,1024,11,77 };
	//vector<int> arr = { 12,5,9,34 };
	cout << "raw val is:\n";
	for (auto i : arr)
		cout << i << "\t";
	cout << endl;

	HeapSort(arr);
	cout << "HeapSort val is:\n";
	for (auto i : arr)
		cout << i << "\t";
	cout << endl;
	system("pause");
	return 0;
}

 

輸出:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章