数据结构:堆排序

「仅为草稿,尚未详解」

堆排序(C语言版)

走进堆排序

什么是堆

堆实质就是一颗完全二叉树,其任何一非叶子节点满足下列性质。

i=1,2,3...n/2

说明:

  既然是完全二叉树,我们就可以用数组来表示!

堆根据上面的性质又分为:

  从中不难发现,大顶堆从上往下依次键值减小小顶堆从上向下键值增大

什么是堆排序

? 对一组待排序记录的关键字,首先把它们按堆的定义建成小(大)顶堆
? 然后输出堆顶的最小(大)关键字所代表的记录再对剩余的关键字建堆以便得到次小(大)的关键字
? 如此反复进行,直到全部关键字排成有序序列为止。

我们先对排序的过程进行了解(已经建好堆)

我曾在优先队列的博客中介绍过大顶堆的这种构造新堆的方法:由上至下的堆有序化。这里同样类似。

  

?我们如何将堆有序转换成我们想要的排序结果呢?

  即,我们想要将这颗完全二叉树变成结果:12 24 30 36 47 53 85 91..
  我们可以不断的执行上诉操作,即不断取出堆顶元素,然后再进行堆有序化,再取出堆顶元素,反复。

核心算法

void HeapAdjust (SqList &H, int s, int m)
{
    for(int j=2*s;j<=m;j*=2)
    {
        if(j<m&&H.r[j].key>H.r[j+1].key) ++j;
        if(H.r[s].key<H.r[j].key) break;
        int temp = H.r[s].key;
        H.r[s].key=H.r[j].key;
        H.r[j].key=temp;
        s=j;
    }

}
void sortByHeapSort(SqList &L)
{
    for(int i=L.length/2;i>0;i--)
    {
        HeapAdjust(L,i,L.length);
    }
    for (int i = L.length; i > 1; --i)    {
        int temp = L.r[1].key;
        L.r[1].key=L.r[i].key;
        L.r[i].key=temp;
        HeapAdjust (L, 1, i - 1); //将H. r[l .. i - 1] 重新调整为大/小顶堆
    }
}

算法分析

  时间复杂度:O(nlog2n) 空间复杂度:O(1)
  是一种不稳定的排序方法

时间: 2024-10-10 13:56:27

数据结构:堆排序的相关文章

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

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

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

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

数据结构——堆排序

堆排序算法就是通过维护一个小根堆或者大根堆的数据结构.小/大根堆本质上是一个完全二叉树.利用了完全二叉树的性质,即完全二叉树节点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表示的是堆的大

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

堆:堆是具有特殊性质的二叉树 每个结点都大于其左右儿子的的二叉树叫大顶堆 每个结点都小于其左右儿子的二叉树叫做小顶堆 堆排序图解: 给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序. 首先根据该数组元素构建一个完全二叉树,得到 然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下: 20和16交换后导致16不满足堆的性质,因此需重新调整 这样就得到了初始堆. 即每次调整都是从父节点.左孩子节点.右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的

数据结构--堆排序

#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

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

堆排序(heap sort) 具体解释 及 代码(C++) 本文地址: http://blog.csdn.net/caroline_wendy 堆排序包括两个步骤: 第一步: 是建立大顶堆(从大到小排序)或小顶堆(从小到大排序), 从下往上建立; 如建堆时, s是从大到小; 第二步: 是依次交换堆顶和堆底, 并把交换后的堆底输出, 仅仅排列剩余的堆, 从上往下建立; 如构造时, s始终是1; 堆排序(Heap Sort)的时间复杂度是O(nlogn), 最坏情况下也是如此. 而高速排序(Quic

[golang] 数据结构-堆排序

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

数据结构堆排序

#include <iostream> #include<stdlib.h> // 创建一个结构体 typedef struct node{ int data; struct node *left,*right; }BiTreeNode; int rear=0,front=0;//全局变量 //创建完全二叉树 BiTreeNode *CreateBiTree(int a[],BiTreeNode **Q,int n){ BiTreeNode *root,*p,*t=NULL; in

Java面试基本知识

Java基本知识 基本知识 服务器:Tomcat 支持Servlet jsp JBoss 开源应用服务器 Apache:最广泛的http服务器,只支持静态网页 String是长度不可变,用+=的时候会生成一个新的String对象,StringBuffer和StringBuilder是可变长度,StringBuffer为线程安全 并发编程:原子性 客观性 有序性 serializable : 静态不能被序列化,被transient修饰的也不能被序列化 面向过程和面向对象: 面向过程:速度快,效率高

15. 蛤蟆的数据结构进阶十五排序实现之堆排序

15. 蛤蟆的数据结构进阶十五排序实现之堆排序 本篇名言:"谁要是游戏人生 ,他就一事无成 ; 谁不能主宰自己 ,永远是一个奴隶.--歌德" 继续来看下堆排序. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/47733553 1.  堆排序 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完全二叉树