十大排序-堆排序

堆排序属于选择排序
选择排序的基本思想:
每一趟(第i趟)在后面n-i+1个待排序的元素中选取关键字最小的元素,作为有序子序列的第i个元素,直到第
n-1趟做完,待排序元素只剩下1个,就不用再选了。

堆排序适合关键字较多的情况(n>1000)
比如:在1亿个数中选出前100个最大值?
首先使用一个大小为100的数组,读入前100个数,建立小顶堆,而后依次读入余下的数,若小于堆顶则舍弃,
否则用该数取代堆顶并重新调整堆,待数据读取完毕,堆中的100个数就是前100个最大值。

最坏时间复杂度:O(nlogn),最好的情况下也是O(nlogn),平均时间复杂度是O(nlogn)
空间复杂度是O(1)
堆排序是不稳定的

#include<bits/stdc++.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>


using namespace std;

void push_up(vector<int> &a,int n)
{
	while(n != 0  && a[(n-1)/2] < a[n])
	{
		swap(a[(n-1) / 2], a[n]);
		n = (n-1)/2;
	}
}

void push_down(vector<int> &a,int size,int n)
{
	int t = n,left = n * 2 + 1, right = n * 2 + 2;
	if(left <= size  && a[left] > a[t])
	{
		t = left;
	}
	if(right <= size  && a[right] > a[t])
	{
		t = right;
	}
	if(t != n)
	{
		 swap(a[n], a[t]);
		push_down(a,size,t);	
	}
}

void heapSort(vector<int> &a, int n )
{
	int size = n - 1;
	for(int i = 0 ; i < n ; i++)
	{
		push_up(a,i);
	}
	for(int i = 0; i < n; i++)
	{
		swap(a[0], a[size]);
		size--;
		push_down(a,size,0);	
	}
}


int main()
{
    int n;
    vector<int> q;
    cin >> n;
    q.resize(n);
    for(int i = 0; i < n; i++)
        cin >> q[i];
    heapSort(q, n);
    for(int i = 0; i < n; i++)
        cout << q[i] << ' ';
    cout << endl;
    return 0;

}

posted @ 2020-07-20 20:19  Akmf's_blog  阅读(116)  评论(0)    收藏  举报