当前位置:网站首页>排序4-堆排序与海量TopK问题
排序4-堆排序与海量TopK问题
2022-07-28 15:28:00 【世_生】
一、堆排序
(1)堆是一颗完全二叉树
(2)堆的每个节点的值都大于或等于其左右孩子节点称为大堆
(3)堆的每个节点的值都小于或等于其左右孩子节点称为小堆
堆:具备着上面条件的就称之为堆
我们可以看出大堆的堆顶是最大值,小堆的堆顶是最小值。
从堆中需要注意:跟节点一定是最大(小)者。
堆的结构:
拿上面大堆做例子:如果将大堆层序遍历存入数组,则满足以下关系
左孩子坐标=2父亲坐标+1
右孩子标=2父亲坐标+2
我们讲这个堆结构,其目的就是为了堆排序用的。
.堆排序算法
堆排序:将待排序的序列构造成一个大(小)堆,整个序列的对大(小)值就是堆顶的根节点。将它拿走,然后把剩余的n-1个序列重新构造成一个堆,就可以得到次大(小)的值,如此反复,便能得到一个有序序列了。
堆的向下调整法:
前提:左右子树必须是堆
通过向下调整,使整颗树都成堆
- 选出左右孩子中小的那一个。
- 小的孩子跟父亲比。
- 如果小的孩子比父亲小,则跟父亲交换,并且把原本的原来孩子的位置继续往下调。
- 如果小的孩子比父亲大,则不需处理,调整完成。
void Swap(int *p,int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
void AdJustDown(int *arr,int n,int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child+1<n && arr[child + 1] < arr[child])
{
child++;
}
if (arr[parent] > arr[child])
{
Swap(&arr[parent],&arr[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
int main()
{
int arr[] = { 27, 15, 19, 18, 28, 34, 65, 44 };
int sz=sizeof(arr)/sizeof(arr[0]);
AdJustDown(arr,sz,0);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
建大堆:
排升序建大堆,排降序建小堆。
- 建大堆
- 自下往上,自右往左

建大堆是自下往上,自右往左
#include<stdio.h>
void Swap(int *p,int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
void AdJustDown(int *arr,int n,int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child+1<n && arr[child + 1] < arr[child])
{
child++;
}
if (arr[parent] > arr[child])
{
Swap(&arr[parent],&arr[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeaqSort(int *arr,int n)
{
//建大堆,自下往上,自右往左。
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdJustDown(arr, n, i);
}
//堆排序
//int end = n - 1;
//while (end>0)
//{
//Swap(&arr[0],&arr[end]);
//AdJustDown(arr,end, 0);
//end--;
//}
}
int main()
{
int arr[] = { 27, 15, 11, 18, 28, 4, 65, 44 };
int sz=sizeof(arr)/sizeof(arr[0]);
HeaqSort(arr, sz);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
堆排序:
void HeaqSort(int *arr,int n)
{
//建堆
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdJustDown(arr, n, i);
}
//堆排序
int end = n - 1;
while (end>0)
{
Swap(&arr[0],&arr[end]);
AdJustDown(arr,end, 0);
end--;
}
}
向下调整法时间复杂的:log2n
建堆时间复杂度:O(N)
堆排序的时间复杂的:O(N*log2N)
建堆如下:
我们用满二叉树来计算,堆的高度为h,假设每层高度为hi,每层节点数为ni,则建堆的时间复杂的为:
故:时间复杂的为O(N)
二、海量TopK问题

思路一:直接堆排序
时间复杂度:O(Nlog2N)
思路二:时间复杂度:O(Nlog2k),空间复杂度O(K)
- 先把数组中K个数据,建成大堆
- 然后剩下的N-K个数,跟堆顶的数据比较,如果比堆顶的数据小,则替换堆顶的数据,然后调整堆(这个堆调整是调整前K个的)。
- 然后堆里面前K个数就是K个小值
void Swap(int *p,int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
void AdJustDown(int *arr,int n,int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child+1<n && arr[child + 1] > arr[child])
{
child++;
}
if (arr[parent] < arr[child])
{
Swap(&arr[parent],&arr[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeaqSort(int *arr,int n)
{
//建堆
for (int i = (n - 1 - 1) / 2; i >= 0; i--)
{
AdJustDown(arr, n, i);
}
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize)
{
int i=k;
HeaqSort(arr,k);
for(int k=0;k<arrSize;k++)
{
printf("%d ",arr[k]);
}
while(i<arrSize)
{
if(arr[i]<arr[0])
{
Swap(&arr[i],&arr[0]);
AdJustDown(arr,k,0);
i++;
}
else
{
i++;
}
}
int*retarr=(int *)malloc(sizeof(int)*k);
for(int j=0;j<k;j++)
{
retarr[j]=arr[j];
}
*returnSize=k;
return retarr;
}
有错误谢谢提出哦。
边栏推荐
- 后台弹出layer提示
- Practical development tutorial of software problem repair tracking system (Part 1)
- R语言使用fs包的file_delete函数删除指定文件夹下的指定文件、举一反三、dir_delete函数、link_delete函数可以用来删除文件夹和超链接
- Stm32f103c8t6 + 0.96 "I2C OLED display 3d_cube
- Roson的Qt之旅#101 Qt Quick中的模型和视图
- 关于web对接针式打印机问题,Lodop使用
- flashfxp 530 User cannot log in. ftp
- 一大早支付宝来短信说你中“奖”了?处理服务器挖矿病毒 - kthreaddi
- LabVIEW LINX Toolkit控制Arduino设备(拓展篇—1)
- R language uses ggpairs function of ggally package to visualize pairwise relationship graph of grouping multivariable, set alpha parameter to change image transparency, diagonal continuous variable de
猜你喜欢

1. Simple command line connection to database

The video Number finds the golden key, and Tiktok imitates the latecomers

HyperMesh自动保存(增强版)插件使用说明

ANSYS二次开发 - MFC界面调用ADPL文件

关于标准IO缓冲区的问题

解决电脑恶意广告弹窗的思路

ANSA二次开发 - 在PyCharm上搭建ANSA/META二次开发环境

一小时内学会Abaqus脚本编程秘籍

Thoughts on solving the pop-up of malicious computer advertisements

Leetcode topic
随机推荐
Fifth uncle's thinking
微信公众号获取素材列表
500million users, four years earlier than wechat... This app, which has been in operation for 15 years, will be permanently discontinued
Detectron2 installation and testing
资本「断供」两年,我只能把公司卖了
Is MySQL query limit 1000,10 as fast as limit 10? If I want to page, what should I do?
About the web docking pin printer, lodop uses
遭MQ连连干翻后的醒悟!含恨码出这份MQ手册助力秋招之旅
mysql查询 limit 1000,10 和limit 10 速度一样快吗?如果我要分页,我该怎么办?
I came across Digital Phoenix coordinate Xuhui Meiluo city in Shanghai
正大杯黑客马拉松数据解析竞赛
Zhengda cup hacker marathon data analysis competition
动态规划 --- 数位统计DP
2021-04-02
ANSA二次开发 - 在PyCharm上搭建ANSA/META二次开发环境
R language ggplot2 visually draws line plots, and uses gghighlight package to highlight the lines that meet the combination judgment conditions in the line graphs (satisfies both condition a and b)
Vm501 development kit development version single vibrating wire sensor acquisition module geotechnical engineering monitoring
Record doc
后台弹出layer提示
R语言使用fs包的file_delete函数删除指定文件夹下的指定文件、举一反三、dir_delete函数、link_delete函数可以用来删除文件夹和超链接