大顶堆以及堆排序

大顶堆的前提是一颗完全二叉树,随后其根节点都大于左右子树 则称为大顶堆 否则为小顶堆 

首先介绍下堆调整,堆是一种数据结构,是一种完全二叉树(不一定是满二叉树),所以根节点与叶子节点满足关系如下:根节点下标为i,左叶子为下标2*i,右叶子下标为2*i+1,当然这里我们用数组来对堆进行存储。堆的子树必须满足如下关系,根节点大于左子树且大于右子树。

堆调整的方法如下,检测根节点是否为叶子节点,是退出,否调出子树中最大的值作为根节点,并对受影响的叶子节点进行递归调整。


主要的博客是这两个 个人感觉写的挺好的

http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

http://www.cnblogs.com/mengdd/archive/2012/11/30/2796845.html 这里面的图可以作为参考

http://www.cnblogs.com/Jason-Damon/archive/2012/04/18/2454649.html

随后主要是堆排序的实现 实质上就是先根部的三个进行排序 把最大的或最小的先找出来,随后与最后一个,或者最后第二个进行调换位置,最后便成为了一个大顶堆  实质上的复杂度为nlogn 并不高

下面附上自己的代码

#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int a[10001];
//调整堆 现在最上面的根和他的左孩子还有右孩子进行比较
//把最大的找出来放在栈顶
void heapAdjust(int a[], int i, int size) {
	//左右孩子的节点先确定
	int lchild = 2 * i;
	int rchild = 2 * i + 1;
	//临时变量
	int max = i;
	//不是叶节点才进行调整
	if (i <= size / 2) {
		if (lchild <= size&&a[lchild] < a[max]) {
			max = lchild;
		}
		if (rchild <= size&&a[rchild] < a[max]) {
			max = rchild;
		}
		if (max != i) {
			int temp = a[i];
			a[i] = a[max];
			a[max] = temp;
			//这一步必须要加 避免max为父节点的子树不是堆
			heapAdjust(a, max, size);
		}
	}
}
//建立最大堆
void BuildHeap(int a[], int size) {
	int i;
	//从第一个不是叶节点的size/2开始建立堆
	for (i = size/2; i >= 1; i--) {
		heapAdjust(a, i, size);
	}
}
//堆排序
void heapSort(int a[], int size) {
	int i;
	BuildHeap(a, size);
	for (i = size; i >= 1; i--) {
		//都将第一个元素和倒数第i元素进行替换,随后进行一次堆的调整
		int temp = a[i];
		a[i] = a[1];
		a[1] = temp;
		heapAdjust(a, 1, i - 1);
	}
}
int main() {
	int n, k;
	while (cin >> n&&n) {
		cin >> k;
		for (int i = 1; i <= n; i++)
			cin >> a[i];
		heapSort(a, n);
		cout << a[k] << endl;
	}
	return 0;
}

要注意一直是逆序的进行排序,也就是size/2 否则会出错

题意是输进n个数 求第k大的数


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值