数据结构——堆排序

堆排序算法就是通过维护一个小根堆或者大根堆的数据结构。小/大根堆本质上是一个完全二叉树。利用了完全二叉树的性质,即完全二叉树节点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表示的是堆的大小,就是size
int s;
//向下维护堆(此代码是小根堆)
void down(int x){
    int t = x;
    //判断x是否小于左右子节点
    if( x*2 <= s && h[x*2] < h[t]) t = x*2;
    if( x*2+1 <= s && h[x*2+1] < h[t]) t = x*2+1;
    //如果x小于了左右子节点,则交换数值
    if( t != x){
        swap(h[t],h[x]);
        //递归维护子节点的子节点
        down(t);
    }
    return ;
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie();
    int n,m;
    cin>>n>>m;
    for(int i = 1 ; i <= n ; i ++ ){
        cin>>h[++s];
    }
    //建堆(堆的初始化),从 n/2 开始维护整个堆的性质(n/2也就是最后一层的上面那层,从n/2开始维护也可以保证整个堆的性质)
    for(int i = s/2 ; i >= 1 ; i -- )
        down(i);

    while(m--){
        cout<<h[1]<<" ";
        h[1] = h[s -- ];
        down(1);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/Flydoggie/p/12283814.html

时间: 2024-10-01 06:44:13

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

数据结构 - 堆排序(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

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

堆:堆是具有特殊性质的二叉树 每个结点都大于其左右儿子的的二叉树叫大顶堆 每个结点都小于其左右儿子的二叉树叫做小顶堆 堆排序图解: 给定一个整形数组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)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆分为大根堆和小根堆,是完全二叉树