重新整理数据结构与算法(c#)—— 堆排序[二十一]
前言
将下面按照从小到大排序:
int[] arr = { 4, 6, 8, 5, 9 };
这时候可以通过冒泡排序,计数排序等。
但是一但数据arr很大,那么会产生排序过于缓慢,堆排序就是一个很好的解决方案。
树的堆,有最大堆和最小堆。
看下最大堆:

它是这样子的,就是说一个节点的大小一定大于它的左节点和右节点大小。
如何利用最大堆。进行从大到小的排序呢?
细节
细节如下:

假如堆排序后:

那么用root(根节点,最大节点)和最后一个数组元素进行交换,那么下次进行堆排序的元素就是length-1个,就不用管最后一个元素,因为最后一个元素已经排好序,且最大。

那么现在回到一个问题上了,就是如何进行最大堆排序呢?
有如下步骤:
1.找到树的最后非叶子节点。arr.length/2-1

现在只需要关注红框的子树。
2.先把最后一个非叶子节点作为子树,进行堆排序。(比较他们的左右节点,把最大的和根节点进行交换)

那么也就是下面已经是最大堆了。
然后在往上比较:

分为两种情况,一个就是加入有节点和根节点进行交换的话,那个节点就要作为子树进行堆排序。
比如这里,4和9要进行交换了,那么下面就不是最大堆了,所以左子树要再次进行最大堆结构化。
代码
static void Main(string[] args)
{
int[] arr = { 4, 6, 8, 5, 9 };
//制作成第一个大顶堆
for (int i=arr.Length/2-1;i>=0;i--)
{
adjustHeap(arr,i,arr.Length);
}
int temp = 0;
for (int j = arr.Length - 1; j > 0; j--)
{
//交换
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
// j 为需要比较元素的个数为:j-1+1=j
adjustHeap(arr, 0, j);
}
foreach (var i in arr)
{
Console.WriteLine(i);
}
Console.ReadKey();
}
public static void adjustHeap(int[] arr,int i,int lenght)
{
int temp = arr[i];
for (int k= 2*i+1;k < lenght; k=2*k+1)
{
if (k + 1 < lenght)
{
if (arr[k] < arr[k + 1])
{
k++;
}
}
if (arr[k] > arr[i])
{
arr[i] = arr[k];
i = k;
}
else
{
//因为下面都是排序好了的
break;
}
}
arr[i] = temp;
}
结果:

性能测试
static void Main(string[] args)
{
//int[] arr = { 4, 6, 8, 5, 9 };
int[] arr = new int[8000000];
for (int i = 0; i < 8000000; i++)
{
arr[i] = (int)((new Random().Next()) * 8000000); // 生成一个[0, 8000000) 数
}
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
//制作成第一个大顶堆
for (int i=arr.Length/2-1;i>=0;i--)
{
adjustHeap(arr,i,arr.Length);
}
int temp = 0;
for (int j = arr.Length - 1; j > 0; j--)
{
//交换
temp = arr[j];
arr[j] = arr[0];
arr[0] = temp;
// j 为需要比较元素的个数为:j-1+1=j
adjustHeap(arr, 0, j);
}
stopwatch.Stop();
Console.WriteLine(stopwatch.ElapsedMilliseconds);
Console.ReadKey();
}
public static void adjustHeap(int[] arr,int i,int lenght)
{
int temp = arr[i];
for (int k= 2*i+1;k < lenght; k=2*k+1)
{
if (k + 1 < lenght)
{
if (arr[k] < arr[k + 1])
{
k++;
}
}
if (arr[k] > arr[i])
{
arr[i] = arr[k];
i = k;
}
else
{
//因为下面都是排序好了的
break;
}
}
arr[i] = temp;
}
测试的时间为:

重新整理数据结构与算法(c#)—— 堆排序[二十一]的更多相关文章
- C#数据结构与算法系列(二十一):希尔排序算法(ShellSort)
1.介绍 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序. 2.基本思想 希尔排 ...
- Java数据结构与算法解析(十二)——散列表
散列表概述 散列表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 散列表的思路很简单,如果所有的键都是整数,那么就可以使用一个简单 ...
- 数据结构与算法16—平衡二叉(AVL)树
我们知道,对于一般的二叉搜索树(Binary Search Tree),其期望高度(即为一棵平衡树时)为log2n,其各操作的时间复杂度O(log2n)同时也由此而决定.但是,在某些极端的情况下(如在 ...
- C#数据结构与算法系列(二十三):归并排序算法(MergeSort)
1.介绍 归并排序(MergeSort)是利用归并的思想实现的排序方法,该算法采用经典的分治策略(分治法将问题分(divide)成一些小的问题然后递归求解, 而治(conquer)的阶段则将分的阶段得 ...
- Java数据结构和算法(十二)——2-3-4树
通过前面的介绍,我们知道在二叉树中,每个节点只有一个数据项,最多有两个子节点.如果允许每个节点可以有更多的数据项和更多的子节点,就是多叉树.本篇博客我们将介绍的——2-3-4树,它是一种多叉树,它的每 ...
- 数据结构与算法问题 AVL二叉平衡树
AVL树是带有平衡条件的二叉查找树. 这个平衡条件必须保持,并且它必须保证树的深度是O(logN). 一棵AVL树是其每一个节点的左子树和右子树的高度最多差1的二叉查找树. (空树的高度定义为-1). ...
- C#数据结构与算法系列(二十):插入排序算法(InsertSort)
1.介绍 插入排序算法属于内部排序算法,是对于欲排序的元素以插入的方式找寻该元素的适当位置,以达到排序的目的 2.思想 插入排序(Insertion Sorting)的基本思想是:把n个待排序的元素看 ...
- 重新整理数据结构与算法(c#)—— 图的深度遍历和广度遍历[十一]
参考网址:https://www.cnblogs.com/aoximin/p/13162635.html 前言 简介图: 在数据的逻辑结构D=(KR)中,如果K中结点对于关系R的前趋和后继的个数不加限 ...
- C#数据结构与算法系列(二):稀疏数组(SparseArray)
1.介绍 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组. 稀疏数组的处理方法是: 1.记录数组一共有几行几列,有多少个不同的值 2.把具有不同值的元素的 ...
- C#数据结构与算法系列(二十二):快速排序算法(QuickSort)
1.介绍 快速排序(QuickSort)是对冒泡排序的一种改进,基本思想是:通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另一部分的所有数据都要小,然后再按此方法对这两部分数 ...
随机推荐
- C++ STL函数对象 仿函数
1 //STL函数对象 仿函数 2 #include<iostream> 3 #include<string> 4 5 using namespace std; 6 7 8 / ...
- Java面试挂在线程创建后续,不要再被八股文误导了!创建线程的方式只有1种
写在开头 在上篇博文中我们提到小伙伴去面试,面试官让说出8种线程创建的方式,而他只说出了4种,导致面试挂掉,在博文中也给出了10种线程创建的方式,但在文章的结尾我们提出:真正创建线程的方式只有1种,剩 ...
- 第12章_MySQL数据类型精讲
第12章_MySQL数据类型精讲 讲师:尚硅谷-宋红康(江湖人称:康师傅) 官网:http://www.atguigu.com 1. MySQL中的数据类型 类型 类型举例 整数类型 TINYINT. ...
- ThreadLocal父子间通信的四种解决方案
ThreadLocal父子间通信的四种解决方案 ThreadLocal 是存储在线程栈帧中的一块数据存储区域,其可以做到线程与线程之间的读写隔离. 但是在我们的日常场景中,经常会出现父线程需要向子线程 ...
- Zabbix技术分享——snmp异常排查指南
大家好,我是乐乐.在IT运维中,难免会碰上设备snmp不通的情况,那么,当问题出现的时候,运维工程师该如何快速找到问题所在呢?下面让我们一起来看看吧! 1.IP配置检查 首先检查zabbix监控上 ...
- vetur volar 是否可以共用,vue2 vue3项目 如何同时开发?
vetur volar 是否可以共用,vue2 vue3项目 如何同时开发? 先提问 以后再找答案 20220704 补答 vetur volar 不要一起装 vscode环境
- AAC编解码移植之基本简介
一 概念 AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术.由Fraunhofer IIS.Dolby Laborato ...
- Spring Boot学习日记11
学习静态资源,和统一打包 WebJars是将web前端资源(js,css等)打成jar包文件然后借助Maven工具,以jar包形式对web前端资源进行统一依赖管理 拿到静态资源 http://loca ...
- Flutter Chanel通信流程
目录介绍 01.flutter和原生之间交互 02.MethodChanel流程 03.MethodChanel使用流程 04.MethodChanel代码实践 05.EventChannel流程 0 ...
- 没想到三天10KStar的营销利器MediaCrawler开源作者已经删库了
前言 一站式社交平台数据抓取利器,带你玩转小红书.抖音.快手.B站和微博数据分析 不经意间,来查看MediaCrawler仓库源码,发现作者已经删库了.看来是领奖了.才几天不到的时间Star数量已经直 ...