数据结构 堆排序原理及其实现

堆:堆是具有特殊性质的二叉树

每个结点都大于其左右儿子的的二叉树叫大顶堆

每个结点都小于其左右儿子的二叉树叫做小顶堆

堆排序图解:

给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

首先根据该数组元素构建一个完全二叉树,得到

然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

20和16交换后导致16不满足堆的性质,因此需重新调整

这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

此时3位于堆顶不满堆的性质,则需调整继续调整

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int q[10005];
void HeapAdjust(int loc,int len)
{
    int pos=loc;                             //最大值的位置(左儿子 右儿子 自己)
    int left_child=2*loc;
    int right_child=2*loc+1;
    if(loc<=len/2)                           //叶子没有左右儿子 所以不用比较
    {
        if(left_child<=len&&q[left_child]>q[pos])             //小顶堆改小于号即可  下同
            pos=left_child;
        if(right_child<=len&&q[right_child]>q[pos])
            pos=right_child;
        if(pos!=loc)                        //最大值不在loc位置   交换后再比较
        {
            swap(q[pos],q[loc]);
            HeapAdjust(pos,len);
        }
    }
    return;
}
void heapsort(int len)
{
    int i;
    for(i=len/2;i>=1;i--)                 //初始化成为大顶堆
        HeapAdjust(i,len);
    for(i=len;i>=1;i--)
    {
        swap(q[1],q[i]);                  //将最大值放置于i处
        HeapAdjust(1,i-1);                //找前i-1个的最大值
    }
    return;
}
int main()
{
    int n,i;
    scanf("%d",&n);                     //输入n个数
    for( i=1; i<=n; i++)
        scanf("%d",&q[i]);
    heapsort(n);
    for(i=1; i<=n; i++)
        cout<<q[i];
    cout<<endl;
    return 0;
}
时间: 2024-08-08 01:45:01

数据结构 堆排序原理及其实现的相关文章

数据结构 - 堆排序(heap sort) 详解 及 代码(C++)

堆排序(heap sort) 详解 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包含两个步骤: 第一步: 是建立大顶堆(从大到小排序)或小顶堆(从小到大排序), 从下往上建立; 如建堆时, s是从大到小; 第二步: 是依次交换堆顶和堆底, 并把交换后的堆底输出, 只排列剩余的堆, 从上往下建立; 如构造时, s始终是1; 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: S

JAVA常用数据结构及原理分析

前不久面试官让我说一下怎么理解java数据结构框架,之前也看过部分源码,balabala讲了一堆,现在总结一下. java.util包中三个重要的接口及特点:List(列表).Set(保证集合中元素唯一).Map(维护多个key-value键值对,保证key唯一).其不同子类的实现各有差异,如是否同步(线程安全).是否有序. 常用类继承树: 以下结合源码讲解常用类实现原理及相互之间的差异. Collection (所有集合类的接口) List.Set都继承自Collection接口,查看JDK

mysql 索引数据结构及原理

原文:http://www.uml.org.cn/sjjm/201107145.asp 1 索引的本质 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构.提取句子主干,就可以得到索引的本质:索引是数据结构. 我们知道,数据库查询是数据库的最主要功能之一,例如下面的SQL语句: 1 SELECT * FROM my_table WHERE col2 = '77 我们都希望查询数据的速度能尽可能的快,因此数据库系统的设计者会从查询算法的角度进行优化.最基本的查询

堆数据结构+堆排序+最大优先队列的堆的实现

对于堆排序,首先要先知道什么是堆数据结构,堆数据结构就是一个完全二叉树,但是它有自己的性质. 例如最大堆的性质为:A[PARENT[i]]>=A[i]:即每一个结点的值大于等于其左右孩子的值,小于等于其父节点的值.我们在这里只讨论最大堆的情况.我们知道一颗完全二叉树对应一个最大堆的形式,我们要做的就是将二叉树转化为最大堆,这就是所谓的最大堆的维护,我们定义函数MaxheapFY(A,i)来进行操作. 代码: /** *MaxheapFY(A,i):维护位置i最大堆性质,此时假设left(i)和r

堆排序原理及其js实现

图文来源:https://www.cnblogs.com/chengxiao/p/6129630.html 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序.首先简单了解下堆结构.堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序.首先简单了解下堆结构. 堆 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩

[golang] 数据结构-堆排序

接上文 树形选择排序上篇也说了,树形选择排序相较简单选择排序,虽然减少了时间复杂度,但是使用了较多空间去储存每轮比较的结果,并且每次还要再和胜出节点比较.而堆排序就是为了优化这个问题而在1964年被两位大佬发明. 原理首先有几个关于树的定义: 如果一棵树每个节点的值都大于(小于)或等于其字节点的话,那么这棵树就是大(小)根树如果一棵大(小)根树正好又是完全二叉树,则被称为大根堆(小根堆) 堆排序就是利用大根堆(小根堆)的特性进行排序的.从小到大排序一般用大根堆,从大到小一般用小根堆. 流程 先把

数据结构——堆排序

堆排序算法就是通过维护一个小根堆或者大根堆的数据结构.小/大根堆本质上是一个完全二叉树.利用了完全二叉树的性质,即完全二叉树节点x的子节点编号为2x和2x+1. 利用这个性质,我们可以让一个一维数组来模拟这个二叉树,数组下标从1开始建立,下标为2*x和2*x+1的就是x的左子树和右子树. #include<bits/stdc++.h> using namespace std; const int N = 100010; //h[n]是堆数组(一维存储) int h[N]; //s表示的是堆的大

数据结构--堆排序

#include <stdio.h> #include <stdlib.h> void MaxHeapify(int a[],int length,int i); void BuildMaxHeapify(int a[],int length); void HeapSort(int a[],int length); void main(void) { int i; int a[10]={1,3,4,2,1,3,2,19,4,0}; printf("Heapsort alg

[地图开发][算法及数据结构]四叉树原理

参考:http://blog.csdn.net/zhouxuguang236/article/details/12312099 原博客地址还有c++源码... 四叉树索引的基本思想是将地理空间递归划分为不同层次的树结构.它将已知范围的空间等分成四个相等的子空间,如此递归下去,直至树的层次达到一定深度或者满足某种要求后停止分割.四叉树的结构比较简单,并且当空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率,因此四叉树是GIS中常用的空间索引之一.常规四叉树的结构如图所示,地理空间对象都