堆排序算法(C#实现)
在软件设计相关领域,“堆(Heap)”的概念主要涉及到两个方面:
一种是数据结构,逻辑上是一颗完全二叉树,存储上是一个数组对象(二叉堆)。
另一种是垃圾收集存储区,是软件系统可以编程的内存区域。
本文所说的堆指的是前者,另外,这篇文章中堆中元素的值均以整形为例
堆排序的时间复杂度是O(nlog2n),与快速排序达到相同的时间复杂度. 但是在实际应用中,我们往往采用快速排序而不是堆排序. 这是因为快速排序的一个好的实现,往往比堆排序具有更好的表现. 堆排序的主要用途,是在形成和处理优先级队列方面. 另外, 如果计算要求是类优先级队列(比如, 只要返回最大或者最小元素, 只有有限的插入要求等), 堆同样是很适合的数据结构.
堆排序
堆排序是一种选择排序。是不稳定的排序方法。时间复杂度为O(nlog2n)。
堆排序的特点是:在排序过程中,将排序数组看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲节点和孩子节点之间的内在关系,在当前无序区中选择关键字最大(或最小)的记录。
基本思想
1.将要排序的数组创建为一个大根堆。大根堆的堆顶元素就是这个堆中最大的元素。
2.将大根堆的堆顶元素和无序区最后一个元素交换,并将无序区最后一个位置例入有序区,然后将新的无序区调整为大根堆。
重复操作,无序区在递减,有序区在递增。
初始时,整个数组为无序区,第一次交换后无序区减一,有序区增一。
每一次交换,都是大根堆的堆顶元素插入有序区,所以有序区保持是有序的。
大根堆和小根堆
堆:是一颗完全二叉树。
大根堆:所有节点的子节点比其自身小的堆
小根堆:所有节点的子节点比其自身大的堆
堆与数组的关系
堆是一种逻辑结构(形象的表示数据的存储格式),数组则是数据的实际存储结构(对应数据的存储地址),堆中的根节点与左右子节点在存储数组中的位置关系如下:假设根节点在数组中的位置(数组下标)为 i ,那么左节点在数组中的位置(数组下标)为 i * 2 + 1 , 右节点在数组中的位置(数组下标)为 i * 2 + 2 。
//堆排序算法(传递待排数组名,即:数组的地址。故形参数组的各种操作反应到实参数组上) private static void HeapSortFunction(int[] array) {try { BuildMaxHeap(array); //创建大顶推(初始状态看做:整体无序) for (int i = array.Length -1; i >0; i--) { Swap(ref array[0], ref array[i]); //将堆顶元素依次与无序区的最后一位交换(使堆顶元素进入有序区) MaxHeapify(array, 0, i); //重新将无序区调整为大顶堆 } }catch (Exception ex) { } } ///<summary>/// 创建大顶推(根节点大于左右子节点)///</summary>///<param name="array">待排数组</param> private static void BuildMaxHeap(int[] array) {try {//根据大顶堆的性质可知:数组的前半段的元素为根节点,其余元素都为叶节点 for (int i = array.Length /2-1; i >=0; i--) //从最底层的最后一个根节点开始进行大顶推的调整 { MaxHeapify(array, i, array.Length); //调整大顶堆 } }catch (Exception ex) { } } ///<summary>/// 大顶推的调整过程///</summary>///<param name="array">待调整的数组</param>///<param name="currentIndex">待调整元素在数组中的位置(即:根节点)</param>///<param name="heapSize">堆中所有元素的个数</param> private static void MaxHeapify(int[] array, int currentIndex, int heapSize) {try {int left =2* currentIndex +1; //左子节点在数组中的位置 int right =2* currentIndex +2; //右子节点在数组中的位置 int large = currentIndex; //记录此根节点、左子节点、右子节点 三者中最大值的位置 if (left < heapSize && array[left] > array[large]) //与左子节点进行比较 { large = left; }if (right < heapSize && array[right] > array[large]) //与右子节点进行比较 { large = right; }if (currentIndex != large) //如果 currentIndex != large 则表明 large 发生变化(即:左右子节点中有大于根节点的情况) { Swap(ref array[currentIndex], ref array[large]); //将左右节点中的大者与根节点进行交换(即:实现局部大顶堆) MaxHeapify(array, large, heapSize); //以上次调整动作的large位置(为此次调整的根节点位置),进行递归调整 } }catch (Exception ex) { } } ///<summary>/// 交换函数///</summary>///<param name="a">元素a</param>///<param name="b">元素b</param> private static void Swap(refint a, refint b) {int temp =0; temp = a; a = b; b = temp; }
堆排序算法(C#实现)相关推荐
- 上标3下标6算法_图解堆排序算法
堆排序定义 一般来说,算法就像数学公式,前人经过不断优化和验证得到有规律性的公式留给后人使用,当然也会交给后人验证的思路.那么堆排序算法就是这样,它有基本固定的定义如下: 1.将数组构建为一颗有规则的 ...
- 9个元素换6次达到排序序列_一文带你读懂排序算法(三):堆排序算法
国庆节快乐~点击上方文字关注我们哦 堆是一种特殊的树形数据结构,其每一个结点都有一个值,通常提到的堆都是指一棵完全二叉树,根结点的值小于(或大于)两个子结点的值,同时,根结点的两个子树也分别是一个堆. ...
- 精通八大排序算法系列:二、堆排序算法
精通八大排序算法系列:二.堆排序算法 作者:July .二零一一年二月二十日 本文参考:Introduction To Algorithms,second edition. ------------- ...
- 堆排序时间复杂度_堆排序算法
堆排序是指利用堆积树这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素.堆是一个优先级队列,对于大顶堆而言,堆顶元素的权值最大.将待排序的数组建堆,然后不断 ...
- 【java排序】 归并排序算法、堆排序算法
一.归并排序算法 基本思想: 归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的.然后再把有序子序列合并为整体有序序列. 归并 ...
- JavaScript实现heapsort堆排序算法(附完整源码)
JavaScript实现heapsort堆排序算法(附完整源码) Heap.js完整源代码 MinHeap.js完整源代码 Comparator.js完整源代码 Sort.js完整源代码 HeapSo ...
- 经典排序算法(7)——堆排序算法详解
堆排序(Heap sort)是指利用堆(最大堆.最小堆)这种数据结构所设计的一种排序算法.堆是一个完全二叉树的结构,并同时满足如下性质:即子结点的键值或索引总是小于(或者大于)它的父节点. 一.算法基 ...
- java 实现 堆排序算法_C程序实现堆排序算法
java 实现 堆排序算法 Heap Sort is a comparison-based sorting algorithm that makes use of a different data s ...
- java 堆排序算法_堆排序算法的讲解及Java版实现
这篇文章主要介绍了堆排序算法的讲解及Java版实现,堆排序基于堆这种数据结构,在本文中对堆的概念也有补充介绍,需要的朋友可以参考下 堆是数据结构中的一种重要结构,了解了"堆"的概念 ...
- php+堆排序算法,PHP实现排序堆排序(Heap Sort)算法
算法引进: 在这里我直接引用<大话数据结构>里面的开头: 在前面讲到 简单选择排序 ,它在待排序的 n 个记录中选择一个最小的记录需要比较 n - 1 次,本来这也可以理解,查找第一个数据 ...
最新文章
- Udacity机器人软件工程师课程笔记(十五)-运动学-正向运动学和反向运动学(其二)-DH参数等
- 记录rewrite url我之前不知道的地方
- svn 迁移到 git 仓库并保留 commit 历史记录
- android系统内置HttpClient库(WebView+ Http(s)URLConnection(ok-http)+ HttpClient(apache-http))
- 阿里妈妈搜索广告CTR模型的“瘦身”之路
- 文件描述符和fcntl及阻塞非阻塞
- 动画讲解C语言的指针,从未如此简单
- 计算机基础及应用笔试,计算机基础及应用测试笔试题
- matlab验潮站,验潮站的作用是什么
- mysql根据语句自动实现索引_mysql 语句的索引和优化
- 控制台应用程序的Main方法
- 计算机无法进入pe系统,u盘启动盘无法进入pe解决方法
- 速腾聚创三维激光雷达 实现cartographer 建图复现工作(代完成)
- 电子计算机的算数,电子计算机的算术/逻辑单元,控制单元合称为____
- 商品进销差价_商品进销差价如何计算及账务处理怎么做?
- 山东科技大学2015-2016学年第一学期程序设计基础期末考试第一场 题解
- Freemarker操作word文档
- 苹果申请声波屏下指纹识别专利 精度足以取代Touch ID
- 逾 200 家港企参与! GoGBA大湾区发展日(广州)圆满举行
- 明日之后mumu模拟器找不到服务器,MuMu模拟器玩明日之后常见问题汇总
热门文章
- mysql悲观锁替代方案_MySQL中的悲观锁和乐观锁
- SpringBoot是如何完成自动配置的
- python执行命令不阻塞_Python 命令行非阻塞输入
- carplay是否可以用安卓系统_Microsoft Teams正在支持CarPlay通话,我还是期待微信支持CarPlay...
- 使用ajax请求cgi,Python CGI同步AJAX请求
- php公众号第三方登录,微信公众号开发小记——3.接入三方登录
- python unittest接口测试_Python+unittest 接口自动化测试
- HID Global推出全新室内定位服务 助力企业优化配置劳动力
- nginx利用geo模块做限速白名单以及geo实现全局负载均衡的操作记录
- 验证iaas的sql服务器出现error configuring vRealize automation server