数据结构与算是:C++实现堆排序

原创 2016年06月01日 14:27:53

堆排序(基于堆的优先队列实现的)

首先介绍一下二叉堆及其相关的算法

1.堆

在二叉堆中,每个元素都有保证大于等于另两个特定位置的元素,根结点是堆有序二叉树中最大结点。

我们有完全二叉树来表示堆,先定下根结点。然后一层一层地由上向下、由左向右,每个结点的下方连接两个更小的结点,直到将N个结点全部连接完毕。

如下图就是一个二叉堆的结构


在一个堆中,位置k结点的父结点的位置为[k/2],而它的两个子节点的位置分别为2k和2k+1。这样可以通过利用数组的索引来存储这个二叉堆。

2.堆的算法

堆的算法:插入元素和删除最大元素

用长度为N+1的数组p[]来表示一个大小为N的堆,不使用p[0]。

在有序化的过程中有两种情况:

   当在堆底加入一个新的元素时或某个元素的优先级上升,需要由下至上恢复堆的顺序;

   当根结点替换成一个较小的元素时或某个结点的优先级下降,需要由上至下恢复堆的顺序。

(1)由下至上的堆有序化(上浮,swim)

当某个结点比它的父结点大的时候,我们需要通过交换这两个元素来恢复堆的有序性。交换以后这个结点有可能比它的父结点还大,那么继续这个过程,直到我们遇到更大结点或者到达根节点。只要记住位置k的父结点的位置为[k/2]。【代码会在下面程序中给出】

应用:插入元素,我们将新元素加到数组的末尾,增加堆的大小并让这个元素上浮到合适的位置

(2)由上至下的堆优化(下沉,sank)

当某个结点比它的两个子结点或者其中之一小的话,通过将它和它的两个结点中的较大者交换来恢复堆的有序性。交换以后这个结点有可能比它现在的两个子结点还小,那么继续这个过程,直到我们遇到比它小的两个结点或者到达堆底。这里记住,位置为k的结点的子结点位于2k和2k+1的位置,注意边界需要与N进行比较。【代码会在下面程序中给出】

应用:删除最大元素,我们从数组的顶端删除最大的元素并将数组的最后的一个元素放到顶端,减去堆的大小并让这个元素下沉到合适的位置。

3.堆排序

堆排序分为两个阶段:堆的构造阶段和下沉排序阶段

(1)构造阶段

堆中每个位置都是一个子堆的根节点,在子堆上使用下沉操作。

(2)下沉操作

删除堆中的最大的元素,然后放人最后元素的位置并缩小数组的大小。

void siwm(int* a, int n, int k) //上浮操作
{
	while (k > 1)
	{
		if (a[k] > a[k / 2]) // 结点k和它的父结点比较大小
		{
			swap(a[k], a[k / 2]); 
			k = k / 2; // 继续向上比较直到到达堆顶或者遇到更大的父结点
		}
		else
			break;
	}
}

void sink(int* a, int n,int k) //下沉操作
{
	while (2 * k < n)
	{
		int j = 2 * k;
		if (a[j] < a[j + 1]) //比较k的两个子结点的大小
			j++;
		if (a[j] > a[k])
		{
			swap(a[j], a[k]); //结点k与最大的那个子结点交换
			k = j; // 继续向下比较直到到达堆底或者遇到更小的两个结点
		}
		else
			break;
	}
}

void heapSort(int* a, int n)
{
	for (int k = n / 2; k >= 1; k--) // 构造堆,使每个子堆符合堆有序
		sink(a, n, k);
	while (n > 1)
	{
		swap(a[1], a[n]); //删除最大的元素并将这个元素与数组尾部的元素替换
		n--; // 缩小数组的大小
		sink(a, n, 1); // 在重复上述过程
	}
}


数据结构基础之堆排序(Java 实现)

总结本文地址 http://blog.csdn.net/never_cxb/article/details/50211631最近做到一道笔试题百度笔试题 有20个数组,每个有500个元素,升序排列,找...
  • never_cxb
  • never_cxb
  • 2015年12月07日 22:07
  • 1702

数据结构之---C语言实现堆排序

数据结构之---C语言实现堆排序
  • u012965373
  • u012965373
  • 2015年09月08日 15:08
  • 7059

JavaScript数据结构之 堆排序

以前没学过这种排序,今天看了一下,最好、最坏时间复杂度都是nlog2n。 原理可以参考这篇博客,里面的图不错 http://blog.csdn.net/xiaoxiaoxuewen/article/...
  • liuyaqi1993
  • liuyaqi1993
  • 2017年04月07日 16:45
  • 451

【数据结构与算法】内部排序之三:堆排序(含完整源码)

堆排序、快速排序、归并排序(下篇会写这两种排序算法)的平均时间复杂度都为O(n*logn)。要弄清楚堆排序,就要先了解下二叉堆这种数据结构。本文不打算完全讲述二叉堆的所有操作,而是着重讲述堆排序中要用...
  • mmc_maodun
  • mmc_maodun
  • 2014年03月04日 00:01
  • 23136

数据结构基础 之 二叉堆实现堆排序

堆实际上是一棵完全二叉树,也称二叉堆。本文首先对二叉堆的定义和相关概念给予阐述并针对堆排序图例给出算法单步演示,而后给出二叉堆以及堆排序的代码实现,文末结合实际代码实现给出算法要点分析。...
  • u013630349
  • u013630349
  • 2015年07月16日 09:41
  • 978

数据结构示例——堆排序过程

完整算法见[例程],本文用一个例子,演示堆排序的过程。例:对{57, 40, 38, 11, 13, 34, 48, 75, 6, 19, 9, 7}进行堆排序的过程。算法如下:void HeapSo...
  • sxhelijian
  • sxhelijian
  • 2015年12月14日 15:43
  • 8398

数据结构之堆排序C语言实现

堆排序: 时间复杂度:O(nlogn) 稳定性:不稳定 实现原理:将待排序的序列构造成一个大顶堆(或小顶堆) 整个序列的最大值就是堆顶的根节点,将它移走 (就是将其与对数组的末尾元素交换,此时末...
  • HSUPERA
  • HSUPERA
  • 2016年07月12日 09:44
  • 385

C++模板堆排序

堆排序简介堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。...
  • zhangxiao93
  • zhangxiao93
  • 2016年03月27日 15:28
  • 648

C语言-数据结构-堆排序(heap sort)-源代码

1. 堆排序 堆排序的定义及思想可以参考百度百科:堆排序 用一句概括,堆排序就是一种改进的选择排序,改进的地方在于,每次做选择的时候,不单单把最大的数字选择出来,而且把排序过程中的一些操作进行了记...
  • kuweicai
  • kuweicai
  • 2017年01月24日 21:07
  • 1393

基本算法_堆排序_Java实现

堆排序就是将序列调整为指定的堆,然后调整首尾元素的位置,取出末尾元素,反复进行,直到将所有元素取出,形成一个有序的序列。...
  • ljmingcom304
  • ljmingcom304
  • 2015年12月22日 14:14
  • 2019
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构与算是:C++实现堆排序
举报原因:
原因补充:

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