堆和堆排序

Posted 哈拉泽空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆和堆排序相关的知识,希望对你有一定的参考价值。

堆排序

堆其实就是一颗完全二叉树,按照每个节点和其儿子节点的大小关系可以分为两种堆

最大堆(Max Heap):所有节点都不小于其儿子节点

最小堆(Min Heap):所有节点都不大于其儿子节点

​ PAT关于堆的练习题:

判断一颗完全二叉树是否是最大堆,最小堆,或者都不是

判断一颗完全二叉树是否是最大堆,最小堆,并对堆进行遍历输出

好了,那么回到正题:堆排序

堆排序的步骤有两个:

  1. 建 最大/最小 堆
  2. 取出堆顶元素(把它在数组中的位置与最后一个元素对调),对剩下的元素再次建堆

假设有n个待排序元素

重复步骤 2 n-1次,数组中的元素就成功的被排序成我们想要的顺序

它利用的原理就是:每次的堆顶元素一定是我们要的 最大/最小 元素

堆排序参考模板:

#include <iostream>
#include <vector>

using namespace std;

void exchange(vector<int>&a,int idx,int length) 
	int tmp=idx;
	int lChild=idx*2+1;//因为下标从0开始
	int rChild=idx*2+2;
	if(a[lChild]>a[tmp]&&lChild<length) tmp=lChild;
	if(a[rChild]>a[tmp]&&rChild<length) tmp=rChild;
	
	if(idx!=tmp) 
		swap(a[tmp],a[idx]);
		exchange(a,tmp,length);
	


void heapSort(vector<int>&a,int length)
	for(int i=length/2-1;i>=0;i--)
		exchange(a,i,length);
	
	
	for(int i=length-1;i>=1;i--)
		swap(a[0],a[i]);
		exchange(a,0,i);
	


void print(vector<int>&a) 
	for(int i=0; i<a.size(); i++) 
		printf("%d%c",a[i],i==a.size()-1?'\\n':' ');
	


int main() 

	int n,num;
	scanf("%d",&n);
	vector<int>array;
	for (int i = 0; i<n; i++) 
		scanf("%d",&num);
		array.push_back(num);
	
	heapSort(array,array.size());
	print(array);
	return 0;


无非两个过程:递归建堆,删除顶点,再递归建堆,循环往复n-1次

学习参考博客

排序 堆排序,C++实现

构造堆的效率是多少?

O(n)

推排序的效率

O(nlogn)

评价:

堆排序不需任何额外的存储空间
针对随机文件的实验指出,堆排序比快速排序运行的慢,但和合并排序还是有竞争力的。

Thanks for watching!

以上是关于堆和堆排序的主要内容,如果未能解决你的问题,请参考以下文章

关于堆和堆排序

堆和堆的应用:堆排序和优先队列

数据结构 | 堆和堆排序

堆和堆排序

堆和堆排序

面试必知必会|理解堆和堆排序