排序算法之堆排序 C语言代码

想要彻底掌握堆排序,你就一定要彻底理解堆排序的过程,原理并进行实践 ,因为我就已经看了很多遍了,还是每记住怎么搞的。

原理:(小顶堆为例子)

小二叉树:即最小二叉树(带两个结点或一个结点)
一颗二叉树父节点总比子节点小(子节点之间没有规定)即(小顶堆二叉树),这样从下看到上,最上面的结点是这棵树里最小的数。(很简单的道理,不懂得话可以试着画一画)

过程

假如现在有一颗这样的二叉树,整个排序的过程是这样的,最上面肯定是最小的,把它和最后一个数字交换位置,代表这个数已经找到了自己在整个数组中的位置,然后把这个数代表的结点给隔离开,剩下的二叉树就再次进行一个建立小顶堆二叉树的过程,找到次小的数字,这样循环往复就可以找到所有数字的位置。那这就涉及到两个大的方面:一是我要先建立一个这样的二叉树,二我要如何将一个交换数字之后的二叉树给恢复到小顶堆二叉树。
整个程序流程

  1. 建立小顶堆二叉树
  2. 开始循环N-1次,将 N-1个数字放到其位置
    2.1.将根节点和末尾结点交换;
    2.2 .剩下子树重新建立小顶堆二叉树
    3.循环结束 排序完成

如何建立小顶堆二叉树

我们先将整个数组无序建立一颗二叉树,然后从最后一棵小子树n=length/2结点树(length/2结点一定含有一个或者两个子结点)把最小的结点推出去,{靠,说不清了} 就这样从n=length/2结点到n=1结点,将n结点为父节点的简单二叉树都变成小顶堆二叉树。

如何恢复小顶堆二叉树

交换之后的二叉树就只有一个根节点不符合小顶堆,就是把这个根节点放到合适的位置上:
1.将n=1结点代表的小二叉树调换成小顶堆
2.这样做可能会破坏左节点或右节点代表的小二叉树,那就继续调整,直到调整到所有的小二叉树都是小顶堆
我去:::对不住各位,语言实在描述太抽象了,还是看代码吧!!少不了的

 #include<stdio.h>
 
 /*
 调整函数,将begin位置到数组最后的树调整为小顶堆
 begin+1到length已经是小顶堆 
 */
 void ad_heap(int a[],int length,int begin)
 {
 	int b=a[begin-1];
    int s =begin;
 	
 	for(int j=begin*2;j<=length;j*=2)
 	{   
 		if(j<length&&a[j-1]>a[j])//这一步是看看子节点是否是最后一个元素,若不是则肯定有兄弟结点,再从兄弟结点中找到最小那个,三者比较,先从兄弟中找到最小的
 		    j++;
 		if(a[j-1]>=b)
 		 break;
 		a[s-1]=a[j-1];
 		s=j;
 		
	 }
	 a[s-1]=b;	 
 }
 int main()
 {
 	int a[7]={49,38,65,97,76,13,27};
 	for(int i =0;i<7;i++)
 	printf("%d\n",a[i]);
 	int length = 7;
 	//这个是难点,length/2在二叉树中表示最后一个基本二叉树 ,
 	for(int i =length/2;i>0;i--)
 	{
 		ad_heap(a,length,i);//调用恢复函数来从底部建立一个完整的小顶堆二叉树 
	 }
	 	
	 for(int j= 1;j<length;j++)
	 { 
	 	int value = a[0];
	 	a[0]=a[length-j];
	 	a[length-j]=value;
	 	ad_heap(a,length-j,1);
	 	
	 }
	 for(int i =0;i<7;i++)
 	printf("%d  ",a[i]);
  } 
 
 
  

我尽力了,兄弟们,最好还是自己写一写,不然你是掌握不了的。。。。。。

发布了37 篇原创文章 · 获赞 1 · 访问量 639

猜你喜欢

转载自blog.csdn.net/zzuzhaohp/article/details/104100165