按名次对数据进行排序cpp_面试中的排序算法(Part 3)
文章和资源同步更新至微信公众号:算法工程师之路
今天来谈一种十分重要的堆排序的法,其在STL中的数据结构也就是Priority_Queue。也是一种十分高效的排序方式,虽然其算法模型为二叉树结构,但是可以使用数据进行模拟这个二叉树的结构和相应的函数操作!
大根堆和小根堆
堆树的定义如下:
- 堆树是一颗完全二叉树
- 堆树的当前节点总是不大于或者不小于其孩子节点的值,如果不大于其孩子节点,叫做小根堆。如果不小于其孩子节点,叫做大根堆
- 堆中每个结点的子树也都是堆树结构
大根堆和小根堆的应用如下图所示,可以根据你需要什么样的排序方式来使用不同的堆结构!
那么我们知道了堆的特性之后,我们就可以使用堆的结构对一个列表进行排序,通常为了编程和实现简单,我们会使用数组来模拟堆结构,假设原始数组为a={4,1,3,2,16,9,10,14,8,7},那么它对应的堆结构(大根堆)为如下图所示:
建立堆以及调整堆
那么我们如何使用数组来表述堆这种结构呢?这里面有一个规律,经过层次遍历后将一个二叉树变成一个数组,如果当前节点的索引值为i,且0<=i<N(从零开始),那么
- 父节点索引为:(i-1) / 2,其中(0-1) / 2 = 0
- 左节点索引为:2*i+1,如果超过索引,则没有左节点
- 右节点索引为:2*i+2,如果超过索引,则没有右节点
当我们清楚的知道这些关系后,我们就可以通过一个数组建立起一个大根堆,核心思路为:
边建立边调整,我们遍历整个数组,遍历的同时比较当前节点(索引为i)和对应的父节点(索引为(i-1)/2),如果没有根节点大,那么就交换两个值,直到遍历完整个列表!
// 建立一个大根堆,时间复杂度为O(N)=O(log1)+O(log2)+...+O(logN)
void heapInsert(vector<int>& list, int index) {while (list[index] > list[(index - 1) / 2]) { // (0-1)/2 = 0swap(list[index], list[(index - 1) / 2]);index = (index - 1) / 2;}
}
当我们的大根堆建立完毕后,如果还需要一个调整堆的函数,也就是说如果一个堆结构发生了变化,比如某一个值的大小发生了变化,那么我们怎样去维持这个结构仍然是大根堆?这是一个heapify的过程!
我们假设索引0的值发生了变化,那么我们首先需要得到其孩子节点较大的值,然后与这个变化后的值比较,如果变化后的值较小,那么就交换两者,接着循环遍历!否则直接退出(由于除了变化的节点相关的,其他节点都继续维持大根堆结构,所以不用判断了)
// 改变一个值,仍然使其为大根堆(将数组看做完全二叉树)
堆排序
当我们得到了这两种堆的操作后,我们就可以完成我们的堆排序了,算法思路很简单,因为难得我们已经说过了!
算法流程:首先对整个列表建立大根堆,则索引0的位置为最大值(毋容置疑),然后将其和最后一个值交换,接着让堆大小减一(已经确定了一个数的位置),由于索引0的值发生了变化,我们需要重新检查和调整其为大根堆(heapify的过程)。接着循环整个过程就可以了,直到堆大小减为0停止!
// 六、堆(大根堆)排序算法
void HeapSort(vector<int>& list) {if (list.size() < 2) {return;}for (int i = 0; i < list.size(); i++) {heapInsert(list, i);}int heapSize = list.size();while (heapSize > 0) {swap(list[0], list[--heapSize]);heapify(list, 0, heapSize);}
}
资源分享
完整测试文件(C++版),文件名为:常见排序算法(重点),请关注我的个人公众号 (算法工程师之路),回复"左神算法基础CPP"即可获得,并实时更新!希望大家多多支持哦~
公众号简介:分享算法工程师必备技能,谈谈那些有深度有意思的算法,主要范围:C++数据结构与算法/深度学习(CV),立志成为Offer收割机!坚持分享算法题目和解题思路(Day By Day)
按名次对数据进行排序cpp_面试中的排序算法(Part 3)相关推荐
- 微软面试中简单的算法题目(转)
微软面试中简单的算法题目(转) (说明:这些题就不是什么花样了,考的是你的基础知识怎么样.再聪明而没有实学的人都将会被这些题所淘汰.) 1.链表和数组的区别在哪里? ANSWER 主要在基本概念上的 ...
- 排序算法 - 面试中的排序算法总结
排序算法总结 查找和排序算法是算法的入门知识,其经典思想可以用于很多算法当中.因为其实现代码较短,应用较常见.所以在面试中经常会问到排序算法及其相关的问题.但万变不离其宗,只要熟悉了思想,灵活运用也不 ...
- 【C 语言】二级指针内存模型 ( 指针数组 | 二维数组 | 自定义二级指针 | 将 一、二 模型数据拷贝到 三 模型中 并 排序 )
文章目录 一.指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中 1.函数形参 设计规则 2.三种内存模型 对应 函数形参 指针退化规则 二.完整代码示例 一.指针数组 和 二维数组 数据 拷贝 ...
- 下划线间隔数字 排序_面试必备:经典算法动画解析之希尔排序
哈喽,我是程序员大鹏. 前面我们介绍了冒泡排序.选择排序和插入排序,今天我们来看一下进阶的排序. 1959年Shell发明,第一个突破O(n2)的排序算法,是简单插入排序的改进版.它与插入排序的不同之 ...
- 在FAANG面试中破解堆算法
In FAANG company interview, Candidates always come across heap problems. There is one question they ...
- 前端面试中常见的算法问题
虽说我们很多时候前端很少有机会接触到算法.大多都交互性的操作,然而从各大公司面试来看,算法依旧是考察的一方面.实际上学习数据结构与算法对于工程师去理解和分析问题都是有帮助的.如果将来当我们面对较为复杂 ...
- oracle和mysql查询条件排序_Oracle数据库中ORDERBY排序和查询按IN条件的顺序输出
ORDER BY非稳定的排序提一个问题: oracle在order by 排序时,是稳定排序算法吗? 发现用一个type进行排序后,做分页查询,第一页的数据和第二页的数据有重复 怀疑是order by ...
- linux配置文件如何排序,Linux系统中sort排序命令的使用教程
sort命令的功能是对文件中的各行进行排序.sort命令有许多非常实用的选项,这些选项最初是用来对数据库格式的文件内容进行各种排序操作的.实际上,sort命令可以被认为是一个非常强大的数据管理工具,用 ...
- 校招面试中常见的算法题整理【长文】
⭐️我叫恒心,一名喜欢书写博客的研究生在读生. 原创不易~转载麻烦注明出处,并告知作者,谢谢!!! 这是一篇近期会不断更新的博客欧~~~ 有什么问题的小伙伴 欢迎留言提问欧. 文章目录 前言 一.链表 ...
- linux中修改mysql排序规则_MySQL中的排序规则
MySQL中的排序规则.在新建MySQL数据库或表的时候经常会选择字符集和排序规则.数据库用的字符集大家都知道是怎么回事,那排序规则是什么呢? 排序规则:是指对指定字符集下不同字符的比较规则.其特征有 ...
最新文章
- SQL Server 2008 的CDC功能
- Tenka1 Programmer Contest C - Align
- vue init webpack缺少标识符_vue 如何从单页应用改造成多页应用_vue.js
- xss攻击突破转义_WEB安全之XSS攻击方式与防御方式
- 隐藏导航条HTML,jQuery实现的导航条切换可显示隐藏
- mnist手写数字识别python_Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】...
- Hbase笔记:批量导入
- android surfaceview view 区别
- 《商务与经济统计》(一)
- 封装解决WebView的那些坑
- pytorch实用工具总结(GFLOPs如何计算)
- SaaS是什么?是订阅吗?还是web应用?
- Vodafone 移动终端声质量评价
- 炼石白小勇:合规与实战推动密码产业发展
- java取拼音首字母
- mysql主键设置了递增,插入语句的写法
- SAT阅读填空练习题五道
- 投资7年,4个独角兽:好的创业公司是什么样子?
- 利用多态特性,创建一个手机类Phones,定义打电话的方式call,创建三个子类,并在各自的方法中重写方法,编写程序入口main()方法,实现多种手机打电话...
- 飘在上海,心路历程【2】2011年11月 反思与拷问