c++实现堆排序

原创 2016年05月31日 21:31:54

在程序设计相关领域,堆(Heap)的概念主要涉及到两个方面:

  • 一种数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆)
  • 垃圾收集存储区,是软件系统可以编程的内存区域。

本文所说的堆,指的是前者。

堆排序的时间复杂度是O(nlgN),与快速排序达到相同的时间复杂度。但是在实际应用中,我们往往采用快速排序而不是堆排序。这是因为快速排序的一个好的实现,往往比堆排序具有更好的表现。堆排序的主要用途,是在形成和处理优先级队列方面。另外,如果计算要求是类优先级队列(比如,只要返回最大或者最小元素,只有有限的插入要求等),堆同样是很适合的数据结构。

基础知识

堆一般用数组表示,比如数组A数组的长度Length(A),堆在数组中的元素个数HeapSize(A)。一般说来,HeapSize(A) <= Length(A),因为数组A当中可能有一些元素不在堆中。

假设节点I是数组A中下标为i的节点。

  • Parent(i) : return Floor(i/2); //I的父节点下标,Floor(i)表示比i小的最大整数。
  • Left(i) : return 2*i; //I的左子节点
  • Right(i) : return 2*i+1; //I的右子节点

含有n个元素的堆A的高度是: Floor(lgn)。

堆的基本操作

  • MaxHeapify( A, i ):

    保持堆的性质。假设数组A和下标i,假定以Left(i)和Right(i)为根结点的左右两棵子树都已经是最大堆,节点i的值可能小于其子节点。调整节点i的位置。

  • BuildMaxHeap( A ):

    从一个给定的数组建立最大堆。子数组A[ floor(n/2)+1 .... ... n]中的元素都是树的叶节点(完全二叉树的基本性质)。从索引 ceiling(n/2)开始一直到1,对每一个元素都执行MaxHeapify,最终得到一个最大堆。

  • 堆排序 HeapSort( A ):

    堆排序算法的基本思想是,将数组A创建为一个最大堆,然后交换堆的根(最大元素)和最后一个叶节点x,将x从堆中去掉形成新的堆A1,然后重复以上动作,直到堆中只有一个节点。

  • 优先级队列算法-增加某元素的值(优先级) : HeapIncreaseKey( A, i, key )

    增加某一个元素的优先级后(元素的值),该元素应该向上移动,才能保持堆的性质。

  • 优先级队列算法-插入一个元素: Insert( S, x ) 将x元素插入到优先级队列S中。

    主要思路是,将堆的最后一个叶节点之后,扩展一个为无穷小的新叶节点,然后增大它的值为x的值。

    c++实现代码

    //HeapSort.h文件
    
    class HeapSort
    {
    public:
    	//HeapSort();
    	//HeapSort(const HeapSort &orig);
    	//virtual ~HeapSort();
    	void shift(int r[], int i, int m);
    	void heapSortInt(int array[], int n);
    private:
    };

    <span style="color: rgb(18, 28, 70); font-family: Verdana, 宋体; line-height: 18px; text-indent: 24px; background-color: rgb(240, 240, 240);">#include "HeapSort1.h"</span>
    using namespace std;
    
    //HeapSort::HeapSort(const HeapSort &orig){}
    //HeapSort::~HeapSort(){}
    
    void HeapSort::shift(int k[], int i, int n) //这个函数就是求三个节点中最大的。
    {
    	int j;
    	int temp = k[i];//i个节点对应的数组值
    	j = 2*i;//左孩的下标
    	while (j <= n)
    	{
    		if (j < n&&k[j] < k[j + 1])
    			j++;              //右孩大
    		if (temp>k[j])        //父节点大
    			break;            //实际上发现只做一次循环,才能用break,否则应该用continue
    		k[j / 2] = k[j];      //大的赋给节点
    		j = j * 2;
    	}
    	k[j / 2] = temp;
    }
    
    void  HeapSort::heapSortInt(int k[], int n)//这个函数实现建堆和排序交换后的调整
    {
    	for (int i = n / 2; i > 0; i--)  //建堆
    		shift(k, i, n);
    	for (int j = n; j > 0; j--)
    	{
    		int temp = k[j];
    		k[j] = k[1];
    		k[1] = temp;
    		shift(k, 1, j - 1); //对发生变化的第一个节点调整
    	}
    }
    

    <pre name="code" class="cpp">#include "HeapSort1.h"
    #include <iostream>
    #include <stdlib.h>
    using namespace  std;
    
    void main()
    {
    	int  n = 10;
    	int a[] = { 0, 12, 432, 436, 54646, 76, 687, 6879, 89, 2, 5 };//第一个元素为0,
    	cout << "大顶堆排序前的序列:" << endl;
    	for (int i = 1; i <= 10; i++)
    	{
    		cout << a[i] << endl;
    	}
    	HeapSort hs;
    	hs.heapSortInt(a, n);
    	cout << "大顶堆排序后的序列:" << endl;
    	for (int i = 1; i <= 10; i++)
    	{
    		cout << a[i] << endl;
    	}
    	system("pause");
    }


    
    

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

堆排序原理及其实现(C++)

堆排序原理及其实现(C++)1 堆排序的引入 我们知道`简单选择排序`的时间复杂度为O(n^2),熟悉各种排序算法的朋友都知道,这个时间复杂度是很大的,所以怎样减小简单选择排序的时间复杂度呢?从上...

堆排序算法的C++实现

堆排序:n*log(n)的时间复杂度, 非稳定排序,原地排序。它的思想是利用的堆这种数据结构,堆可以看成一个完全二叉树,所以在排序中比较的次数可以做到很少。加上他也是原地排序,不需要申请额外的空间,效...

堆排序——C++关于堆排序的库函数排序

C++中对于堆排序算法,其实是有一个专门的库函数:sort_heap void sort_heap (RandomAccessIterator first, RandomAccessIterato...

C++ 堆排序算法(大堆)

#include using namespace std; //对中的根元素从0开始 void adjustHeap(int list[],int root,int n) {  int tempro...

C++ 堆排序

首先让我们一起了解一下堆的定义。 最大堆:后者任一非终端节点的关键字均大于或等于它的左、右孩子的关键字,此时位于堆顶的节点的关键字是整个序列中最大的。(堆的定义是递归的) #include ...
  • fu_zk
  • fu_zk
  • 2012年12月14日 10:28
  • 5437

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

堆排序(C++实现)

堆有最大堆和最小堆之分,最大堆就是每个节点的值都>=其左右孩子(如果有的话)值的完全二叉树。最小堆便是每个节点的值都...

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

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

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

自底向上实现堆排序

堆排序是变治法的一个实例 以实现大根堆为例 首先,设置一个数组h[N]存储堆,第一个元素h[0] = INF,不作使用,堆元素从1到n; 其次,完全二叉树是指:除最后一层,树的每层是满的...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++实现堆排序
举报原因:
原因补充:

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