堆排序及top-k问题

news/2024/10/22 18:52:29/

堆排序及top-k问题

  • 堆排序
    • 建堆
      • 向上调整建堆
      • 向下建堆
    • 堆排序
  • top-k问题,建堆的应用

堆排序

堆排序,听名字就是要对堆进行排序,但当我们是无序数据时,首先我们就需要建立一个堆
在这里插入图片描述

建堆

这里让我们来回忆一下前面的堆,改变堆的数据顺序我们有向上调整和向下调整。

向上调整建堆

在这里插入图片描述
这是向上调整堆的思路。

当我们对一个数据进行向下调整时,首先要保证上面都成堆。
在这里插入图片描述

那我们从最上面一个一个进行向上调整
不就可以保证上面都是堆了嘛。

在这里插入图片描述
1:arr[0]进行建堆
2:对arr[0],arr[1]进行建堆
3:对arr[0],arr[2],arr[3]进行建堆
………………………………
这样就能保证对堆的第n个数据进行调整时,n以上的所有数据都成堆

void Swap(int* arr, int x, int y)
{int tmp = arr[x];arr[x] = arr[y];arr[y] = tmp;
}
void adjustup(int* a, int child)
{int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){Swap(a, child, parent);child = parent;parent = (parent - 1) / 2;}elsebreak;}
}
void creatheap(int* arr,int size)
{for (int i = 0; i < size; i++){adjustup(arr, i);}
}
int main()
{int arr[20] = { 54,76,23,58,167,367,235,651,764,126,538,12,79,23,46,13,67,38,30,15 };creatheap(arr,20);for (int i = 0; i < 20; i++)printf("%d ", arr[i]);return 0;
}

在这里插入图片描述
这样我们就得到了一个大根堆。
(大根堆和小根堆就差在adjustup所以这里就不举大根堆的例子了)

向下建堆

在这里插入图片描述
这是向下调整的思路,同向上调整一样,向下调整则是要求下面的数都是堆。

在这里插入图片描述

所以比较于前面的向上调整是从上面一个一个调整,向下调整是要从下面开始一个一个调整

那我们就要从最底下的19一个一个开始调整嘛?
其实也不用这么麻烦
我们可以从30开始的最后一个根开始一个一个调整。
在这里插入图片描述
1:调整30这个最后一个根
2:调整25这个根
3:调整7这个根,前面调整了30和25,保证了n下面的数据都成一个堆

void Swap(int* arr, int x, int y)
{int tmp = arr[x];arr[x] = arr[y];arr[y] = tmp;
}
void AdjustDown(int* a, int n, int parent)
{int child = 2 * parent + 1;while (child < n){if (child + 1 < n && a[child] < a[child+1]){child++;}if (a[child] > a[parent]){Swap(a, child, parent);parent = child;child = parent * 2 + 1;}else{break;}}
}
void creatheap(int* arr,int size)
{for (int i = (size-1-1)/2; i>=0; i--){AdjustDown(arr,size,i);}
}
int main()
{int arr[20] = { 54,76,23,58,167,367,235,651,764,126,538,12,79,23,46,13,67,38,30,15 };creatheap(arr,20);for (int i = 0; i < 20; i++)printf("%d ", arr[i]);return 0;
}

这样就建好了一个大根堆。

堆排序

在这里插入图片描述
当我们建立好一个大根堆时

我们发现大根堆的特点是其最顶端的数据一定是最大的一个数。
这里我们就能想到
为什么我们不每次取出顶端最大的值,然后再进行向下调整,然后再得到最大值,不断循环呢?

这里确实是这样一个思路,但是我们在我们取出最大值时,那最大值要用什么数来填补呢?
这个时候我们就能想到堆的删除数据操作了。
在这里插入图片描述
这就是我们的交换删除法。
完美契合堆排序的要求。

void creatheap(int* arr,int size)
{
//前面建堆的部分for (int i = (size-1-1)/2; i>=0; i--){AdjustDown(arr,size,i);}int end = size - 1;//排序部分while (end >= 0){Swap(arr, 0, end);end--;AdjustDown(arr, end+1, 0);}
}


结果也是完美的正确了。

top-k问题,建堆的应用

问题:在一堆数据中,选出k个最大(最小)的数据

解决思路:如果要选取最大的k个数
1:在数据前k个建小根堆
2:遍历数据k后的每个数,如果大于小根堆的顶部数据,则将两个数据进行交换
3:对新的顶部数据进行向下调整,使顶部的数据重新变回k堆的最小值。
4:直到数据遍历完成,最后输出即可。

这里就不贴代码了,就交给感兴趣的人自己去完成吧


http://www.ppmy.cn/news/45372.html

相关文章

【C/C++】C++ 四种强制转换

文章目录 基本概念适用场景及代码案例测试运行Demo 基本概念 C 中有四种强制转换方式&#xff0c;分别是&#xff1a; static_cast&#xff1a;用于基本数据类型之间的转换&#xff0c;以及具有继承关系的指针或引用之间的转换。static_cast 在编译时进行类型检查&#xff0c;…

计算机视觉的热门研究方向与发展趋势

计算机视觉产业链 工业界&#xff1a;对学术研究提出需求 最火的两个概念&#xff1a;自动驾驶和元宇宙 相关热点研究方向&#xff1a; &#xff08;1&#xff09;建图技术&#xff1a;三维重建技术&#xff0c;包括SLAM、定位、建图、更新等技术&#xff1b;&#xff08;2&…

基于LDA+SVM实现人脸识别模型

基于LDASVM实现人脸识别模型 描述 人脸识别&#xff08;图像识别&#xff09;是机器学习领域十经典的应用&#xff0c;在本质上&#xff0c;人脸识别属于监督学习中的分类问题。前面章节中我们已经学习了支持向量机&#xff08;SVM&#xff09;&#xff0c;该算法在图像分类领…

又一科研利器诞生!能对话的论文阅读器,hammerScholar

文&#xff5c;智商掉了一地 hammerScholar 新升级&#xff0c;用对话式读论文工具提升科研生产力~ 不得不说&#xff0c;自从 AIGC 这个概念出现以来&#xff0c;它极强的内容理解与生成能力也推动着各种生产力工具层出不穷&#xff0c;除了一些浏览器和代码插件以外&#xff…

26岁转行网络安全,成功上岸安全开发!

前言 我是去年 9 月 22 日才正式学习网络安全的&#xff0c;之前在国营单位工作了 4 年&#xff0c;在长沙一个月工资只有 5000 块&#xff0c;而且看不到任何晋升的希望&#xff0c;如果想要往上走&#xff0c;那背后就一定要有关系才行。 而且国营单位的气氛是你干的多了&a…

我去蔚来试驾了

前面写了比亚迪汉、小鹏P7i的试驾体验&#xff0c;链接如下&#xff1a; 小鹏P7I试驾体验&#xff01; 今天接着分享蔚来ET5的试驾体验&#xff0c;实话实说&#xff0c;我是蔚来ET5的颜粉&#xff0c;颜值也是ET5最大的卖点之一。 我身边不少朋友&#xff0c;不管是男生还是女…

物联网安全性测试和常见漏洞

物联网安全性测试和常见漏洞 尽管物联网&#xff08;IoT&#xff09;重新定义了我们的生活并带来了很多好处&#xff0c;但它的攻击面很大&#xff0c;并且在安全之前是不安全的。如果没有适当的保护&#xff0c;物联网设备很容易成为网络犯罪分子和黑客的目标。您可能会遇到财…

VMware ESXi 8.0U1 发布 - 领先的裸机 Hypervisor

请访问原文链接&#xff1a;https://sysin.org/blog/vmware-esxi-8-u1/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023-04-18, VMware vSphere 8.0U1 发布。 详见&#xff1a;VMware vSphere 8 Update 1 新增功能 产品简…