大顶堆以及堆排序

原创 2015年11月17日 20:00:16

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

首先介绍下堆调整,堆是一种数据结构,是一种完全二叉树(不一定是满二叉树),所以根节点与叶子节点满足关系如下:根节点下标为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大的数


版权声明:本文为博主原创文章,未经博主允许不得转载。

Java 堆排序(大顶堆、小顶堆)

引用:http://lib.csdn.net/article/datastructure/8973 堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结...
  • Sun_Ru
  • Sun_Ru
  • 2016年07月23日 14:10
  • 5466

堆排序(大顶堆)

一:堆 堆可以看做一个完全二叉树,同时该完全二叉树满足双亲结点大于等于孩子结点(大顶堆),或者双亲结点小于等于孩子结点(小顶堆)。 二:堆排序(以大顶堆为例) 大顶堆产生顺序序列...
  • simatongming
  • simatongming
  • 2017年05月16日 16:51
  • 358

快速排序、归并排序、大顶堆排序、希尔排序代码实现

快速排序 O(n*log2_n) O(log2_n) 不稳定 归并排序 O(n*log2_n) O(n) 稳定 大顶堆排序 O(n*log2_n) O(1) 不稳定 希尔排序 O(n*log2_n) ...
  • ls667
  • ls667
  • 2016年09月08日 00:15
  • 329

堆排序(大顶堆->升序)

#include #include /* 堆排序 */ void HeapAdjust(int a[],int index,int n) { //注意规定a[0]不存放元素,当做缓存用 ...
  • CreazyApple
  • CreazyApple
  • 2012年09月22日 10:26
  • 3273

堆排序,大顶堆,小顶堆

代码如下,有详细的注视 package com.collonn.algorithm.sort; /** * * 堆排序基本步骤,假设没有重复的元素 * 空间:为O(1) * 时间:N...
  • collonn
  • collonn
  • 2014年02月10日 15:50
  • 11300

排序——堆排序-大根堆(大顶堆)

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值;若根节点存在右子女则根节点的值小于右子女的值。 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值;若根节点存在右子女则根节点的值大于右...
  • laoniu_c
  • laoniu_c
  • 2014年08月12日 12:46
  • 3901

大顶堆排序

堆排序的思想借助了二叉排序树,时间复杂度:O(NlgN),空间复杂度O(1)。  基本思想:把待排序的元素按照大小在二叉树位置上排列,排序好的元素要满足:父节点的元素要大于等于其子节点;这个...
  • chenwiehuang
  • chenwiehuang
  • 2017年12月12日 10:46
  • 134

堆排序 (建立大顶堆)

/*堆栈排序:建立大顶堆*/ void HeadAdjust(HeapType &H , int s , int m ) { /*已知H.r[s..m]中记录的关键词除了H.r[s].key之...
  • wenlovingliu
  • wenlovingliu
  • 2013年06月03日 22:08
  • 1152

堆排序,插入,删除,调整算法(大顶堆)

#include #include /*堆以数组为组织方式,下标从0开始*/ #define INIT_ARRAY_SIZE 50 /*函数声明部分*/ void build_...
  • youwuwei2012
  • youwuwei2012
  • 2014年06月19日 13:44
  • 818

Java堆排序(大顶堆)

/*堆排序*/ class HeapSort { // 对data数组从0到lastIndex建大顶堆 public static void buildMaxHeap(int[] data , ...
  • u013453970
  • u013453970
  • 2015年08月06日 10:49
  • 787
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:大顶堆以及堆排序
举报原因:
原因补充:

(最多只允许输入30个字)