大顶堆以及堆排序

原创 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大的数


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

相关文章推荐

大顶堆第二弹----堆排序(递归实现)

1 package com.datastruct; 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 ...

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

#include #include /*堆以数组为组织方式,下标从0开始*/#define INIT_ARRAY_SIZE 50/*函数声明部分*/void build_heap(int par_ar...

堆排序(大顶堆)

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

Java堆排序(大顶堆)

/*堆排序*/ class HeapSort { // 对data数组从0到lastIndex建大顶堆 public static void buildMaxHeap(int[] data , ...

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

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

建小顶堆和大顶堆排序算法(数据结构经典)

/************************************************************ Function: 堆排序 Author: glq2000[glq20...

堆排序,大顶堆,小顶堆

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

建大顶堆和小顶堆及堆排序算法

/************************************************************     Function: 堆排序        Author: glq...

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

1.小根堆 若根节点存在左子女则根节点的值小于左子女的值;若根节点存在右子女则根节点的值小于右子女的值。 2.大根堆 若根节点存在左子女则根节点的值大于左子女的值;若根节点存在右子女则根节点的值大于右...

《排序算法》——堆排序(大顶堆,小顶堆,Java)

堆的定义如下:   n个元素的序列{k0,k1,...,ki,…,k(n-1)}当且仅当满足下关系时,称之为堆。   " ki=k2i,ki>=k2i+1.(i=1,2,…,[n/2])"   若将和...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:大顶堆以及堆排序
举报原因:
原因补充:

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