基于C#的堆排序

news/2024/5/19 3:38:49 标签: 堆排序, 排序算法

堆是一种完全二叉树,也叫二叉堆。
分别分为两种类型: 最大堆 以及 最小堆;

最大堆(大顶堆), 所有父节点都大于子节点
最小堆(小顶堆), 所有父子点都小于子节点

右为 大顶堆,
左为 小顶堆,

根节点叫堆顶 , 根节点一定是 整个堆中 最小/最大的。
在这里插入图片描述

堆排序利用这个 特点进行排序。
每次 它调整后, 最大的节点或最小的节点 总是排到第一位去,
那么 可以让最大 节点 存储到它 最大的节点编号上, 这样 最后一位就是保存了 所有节点中最大的节点了,依次的, 把第二大的浮去上,再放到 第二大的节点编号上,直到 最后 放到 2号 上。

在这里插入图片描述

构建大定堆的 思路:就是让所有的 非叶子节点(父节点) 与它的两个子节点
依次比较 ,保存最大。
从最后一个非叶子节点开始 依次比较保存 最大。

上图 最后一个非叶子 节点 编号 是4 它的值是 60, 它会和 编号8,9 进行比较 ,如果需要交换,需要 再去从交换过的 索引开始 对它 进行调整

然后再从 编号3 开始,它的值是80, 它会 和 编号 6,7进行 比较。
,如果需要交换,需要 再去从交换过的 索引开始 对它 进行调整

然后再从 编号2 开始 它的值是70,它会和编号4,5进行比较。
,如果需要交换,需要 再去从交换过的 索引开始 对它 进行调整

最后 从编号1开始,它的值是90,它会和编号2 和3 进行 比较。

完全二叉树中,它的左子节点 编号 是父节点编号的两倍。
即 leftIndex=2fatherIndex;
它的右节点是 左节点加上1,
即 rightIndex=2
fatherIndex+1
逆推 可以得
fatherIndex=leftIndex/2;
fatherIndex=(rightIndex-1)/2;

最后一个非叶子节点编号,就是最后一个节点的 父节点,
完全二叉树中 最后一个 节点 一定是 右子节点。
所以 非叶子节点编号公式 为
(length-1)/2

知道这个 就可以进行调整了。

//从 调整num编号的元素, 仅仅是调整一个 
 void HeapAdjust(int numToAdjust,int[] nums,int maxLimit)
 {
	    int i=numToAdjust;
		int tempMaxNum=i; //保存 最大
		while(true)
		{
			int left= i*2;
			int right= i*2+1;
	
			//节点 存在  且是它的值是最大的 
			if(left<maxLimit&& nums[left-1]>nums[tempMaxIndex-1])
			{
			 	tempMaxNum=left;
			}
			if(rightt<maxLimit&&nums[right-1]>nums[tempMax-1])
			{
			 	tempMaxNum=right;
			}
			//需要交换
			if(tempMaxNum!=i)
			{
				int temp=nums[temMaxNum-1];
				nums[temMaxNum-1]=nums[i];
				nums[i]=temp;
			 	i=tempMaxNum;//再从交换过的节点 进行调整
			}else//不需要调整退出
			{
				break; 
			}
		}
 }
void BuildHeap(int[] nums)
{
	//从最后一个非叶子节点开始
	for(int i=nums.Lenght/2;i>0;i--)
	{
		HeapAdjust(i,nums,nums.Length);
	}
}

void HeapSort(int[] nums)
{
	BuildHeap(nums);//构建 大定堆  
	for(int i=nums.Length-1,i>1;i--)
	{
		int temp=nums[i];
		nums[i]= nums[0];
		nums[0]=temp;
		//首尾交换  再进行调整堆 最后一个节点不需要 交换了  也就不用+1了  
		//因为 编号 比索引多1
		 HeapAdjust(1,nums,i); 
	}
}

http://www.niftyadmin.cn/n/770084.html

相关文章

lua表深拷贝和浅拷贝

前言 lua表是一种常用的数据结构,底层实现分为散列表和数组。 表可以理解为引用类型&#xff0c;也就是说&#xff0c;如果把一个表的对象赋值给另一个变量&#xff0c;那么得到的其实是这个表的内存地址。 例子1&#xff1a; local t10{1,2,3,4,5,6} local t9t10 t9[1]10 pri…

哲学家就餐问题(java实现)

1 问题概述 哲学家就餐问题&#xff0c;是并行程序中的一个经典问题&#xff0c;其描述如下。 1. 圆桌上有五位哲学家&#xff0c;每两人中间有一个筷子。 2. 每个哲学家有两件事情要做&#xff1a; (1) 思考&#xff1b; (2) 吃饭。哲学家必须同时拿到两只筷子&#x…

有效的数独

LeetCode 之 有效的数独 判断一个 9x9 的数独是否有效。只需要根据以下规则&#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。 上图是一个部分填充的有…

Lua协程实现原理

相关 API API 传入参数 返回值 说明 API传入参数返回值说明create(f)函数&#xff0c;作为协程运行的主函数返回创建的协程如果还需要运行&#xff0c;需要使用resume操作resume(co,[val1,…])传入第一个参数是create函数返回的协程&#xff0c;剩下的参数是传递给协程运行的…

百度网盘搜索引擎

百度网盘搜索&#xff1a; 1 .网盘屋&#xff1a;http://www.wangpanwu.com 这里已经有很多热门资源&#xff0c;分享达人&#xff0c;排行什么的。很容易利用达人分享空间收集资源。 2.度盘搜&#xff1a;http://www.dupansou.com/ 这还有一个主站和华为站。不过主站貌似搜不到…

windows系统下mysql修改默认字符编码

问题&#xff1a;由于安装MySQL时没有修改默认的字符编码&#xff08;liatin1&#xff09;,运行时发现保存不了中文 修改MySQL字符编码方法如下&#xff1a; 关闭MySQL服务 dos命令关闭&#xff1a;net stop mysql 手动关闭&#xff1a;如图修改MySQL的安装目录下的my.ini(My…

关于Unity中渲染的优化

前言 最近在看shader入门精要一书&#xff0c;里面大概指出了GPU的优化&#xff0c;入门精要嘛。 翻阅官方文档&#xff0c;和参考一些博文&#xff0c;比较杂&#xff0c;因此&#xff0c;很有必要整理&#xff0c;这篇文章主要是针对渲染相关的&#xff0c;和CS脚本&#xf…

Hibernate4.3.11 如何去掉红色的日志文字

​ 四月13, 2017 2:41:11 下午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations {4.0.5.Final} 四月 13, 2017 2:41:11 下午 org.hibernate.Version logVersion INFO: HHH000412: H…