首页 > 其他分享 >堆排序heapSort_legend

堆排序heapSort_legend

时间:2022-12-13 17:39:01浏览次数:45  
标签:temp int maxChild heapSort 元素 堆排序 start data legend

堆排序:

(一)定义:

从小到大排序则构建一个最大堆;从大到小排序,则构建一个最小堆。
(二)思想:
1.先建立一个最大堆;
2.然后将最大堆的堆顶元素(0号元素,最大值)与堆的最后一个元素(n-1号元素)交换,这样最后一个元素(n-1号)就保存的是最大值了。然后堆的个数-1;调整堆siftDown,(是从0号到n-2号调整),这样就可以在堆顶获得第二大的元素。
3.重复2;
4.最终从n-1号元素到0号元素,存储的就是递减的顺序。

所以:
(1)递增排序,应该构建一个最大堆。
(2)递减排序,应该构造一个最小堆。

(三)优点,适用于:

(1)优点:
堆的优点在于最快的 找到最大,最小值。取走最大,最小值后重新构成堆,其时间复杂度为O(lgn),其他方法一般至少都需要O(n);
(2)适用于:
1.调度算法中,取最高优先级。
2.求取TopN问题或者第N大/小问题。

(四)步骤:
(1)建堆:
1.siftdown;
2.buildHeap:
(2)堆排序:

(五)代码实现:

/*
从start~end,只有start这个位置不满足最大堆,其余位置满足最大堆的定义。
所以从start到end开始调整。
*/
//注意:siftdown是将start处的值data[strat]保存下来为temp,然后将temp的值不断往下调整。所以每次都是孩子中较大的与temp的比较。
void siftDown(HeapType data[], int start ,int end ){ int maxChild=start*2+1;//初始化孩子中较大的一个为左孩子。
HeapType temp=data[start];//保留值,挖一个坑。 for(;maxChild<=end;){
if(maxChild+1<=end && data[maxChild]<data[maxChild+1] )
maxChild++;//取左右孩子中较大的一个。 if(data[maxChild]<temp) break;
else {
data[start]=data[maxChild];//将较大的孩子填充到父节点中。
//较大的孩子节点有了一个坑
start=maxChild;//更新父节点为儿子节点,继续向下比较。maxChild=2*start+1;
}
} data[start]=temp;
}
/*
构建堆,从下到上的非叶子节点,每一个非叶子节点从上往上的siftDown调整。
n为节点个数,即数组长度。
*/
void buildHeap(HeapType data[], int n){
int mid=(n-1)/2; for(;mid>=0;mid--){
siftDown(data,mid,n-1);
}
}/*
堆排序:n为叶子个数,即数组的长度。
*/
void heapSort(HeapType data[], int n){
buildHeap(data,n);//先构造一个堆、 for(int i=n-1;i>=0;i--){
HeapType temp=data[0];//交换堆顶(0号元素)与堆的最后一个元素。
data[0]=data[i];
data[i]=temp; sitfDown(data,0,i);//堆的大小i不断的减小
}
}

(六)堆的应用:

(1)求取TopN问题或者第N大/小问题:

1.topN大(即:最大的N个数),则采用最小堆,且堆顶元素为第N大的元素;
2.topN小(即:最小的N个数),则采用最大堆,且堆顶元素为第N小的元素;

如:已知文件中有10000个数据,求取其中的最大的100个数据,现在的内存限制为100个数据。

思想:
1.前100个数,建立一个最小堆;
2.然后i 从个101~10000, 当前元素data[i]与堆顶比较,如果比堆顶大,则覆盖堆顶,然后siftDown调整。
3.重复2直至结束,则最小堆里则为最大的100个数,且堆顶为第100大的数。

(2)快速求取,最大,最小值。



标签:temp,int,maxChild,heapSort,元素,堆排序,start,data,legend
From: https://blog.51cto.com/u_15911260/5934903

相关文章

  • 生产者与消费者问题------legend050709
    生产者与消费者问题: (一)基础:(1.0)生产者消费者的背景1》为了平衡生产者和消费者的处理能力,起到一个数据缓存的作用,同时也达到了一个解耦的作用在多线程开发中,如果生产者生......
  • gcd && 素数_legend
    数据处理:(1)gcd(GreatestCommonDivisor):gcd详解:(2)素数(质数)(primenumber): (2.1)判断素数:  (2.1.1)试除法:  (2.1.2)筛选法: (2.2)前N个素数: (2.3)小于等于N的素数......
  • 线性表(链表,顺序表)讲解_legend
    线性表(linearList)(1)线性表的定义:节点(node)之间具有一对一的前驱后继关系(2)线性表的存储结构:(2.1)顺序表(sequenceList):(2.2)链式表(linkList):(3)顺序表的常见操作:(初始化+增删改......
  • 数组的扩展操作_legend
    顺序表sequeceList的扩展操作:(1)数组中的最小元素,以及最小的K个元素:(2)数组中重复次数最多的元素:mostRepeated(2.1)数组中出现次数超过一半的元素:(2.2)出现次数刚好为一半......
  • 单链表的扩展操作21----legend050709
    单链表的操作之补充: (1).单链表的反转: (2).单链表的排序(插入排序,选择排序,冒泡排序等): (3).单链表取得最小值的节点,及其前驱: (4).单链表获取最小的k个节点:(4-1)单链表......
  • Catlan数之栈的出栈序列-legend
    栈的出队顺序问题:(一)Catlan数:(1)给出入栈序列,求出所有的出栈的序列个数: C(2n,n)/(n+1);(2)给出入栈序列,求出所有的出栈序列;1)举例:1、2、3这三个数字,入栈并出栈共有5种方式,分......
  • 约瑟夫环问题——legend
    约瑟夫环问题:(一)问题:已知有n个人(编号为1,2,3...n)围坐在一个圆桌周围,从编号为k的人开始报数,数到m的那个人出队,出队的下一个位置的人继续从k开始数数,数到m的那个人继续......
  • 堆排序
    比较常见的排序方法,见例题:本题要求实现堆排序中的筛选函数,待排序列的长度1<=n<=1000。函数接口定义:voidHeapAdjust(HeapTypeH,ints,intm);其中L是待排序表,使排......
  • 堆排序
    输入一个长度为 n 的整数数列,从小到大输出前 m 小的数。#include<iostream>usingnamespacestd;constintN=1e5+10;intn,m,len;inth[N];voiddown......
  • 与堆和堆排序相关的问题
    与堆和堆排序相关的问题作者:Grey原文地址:博客园:与堆和堆排序相关的问题CSDN:与堆和堆排序相关的问题堆结构说明堆结构就是用数组实现的完全二叉树结构,什么是完全二叉......