码迷,mamicode.com
首页 > 编程语言 > 详细

建堆,以及对堆排序

时间:2017-05-02 13:42:42      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:let   can   自己   lag   amp   最大   ret   max   sort   

                                        建堆,以及堆排序

代码1:
#include<stdio.h>
int h[101];//用来存放堆的数组 
int n;//用来存储堆中元素的个数,就是堆的大小 
//交换函数,用来交换堆中的俩个元素的值 
void swap(int x,int y)
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
}
//向下调整函数 
void siftdown(int i)
{//传入一个须要向下调整的的节点编号i,这里传入1。即从堆的顶点開始向下调整 
	int t,flag=0;//flag用来标记是否须要继续向下调整
	//当i节点有儿子(事实上是至少有左儿子)而且有须要继续调整的时候循环就运行 
	while(i*2<=n&&flag==0)
	{
		//首先推断它与左儿子的关系。而且t记录值比較小的节点编号 
		if(h[i]>h[i*2])
		{
			t=i*2;
		}
		else
	    {
	    	t=i;
		}
		//假设它有右儿子,再对右儿子进行讨论 
		if(i*2+1<=n)
		{
			//假设右儿子的值更小。更新较小的节点编号 
			if(h[t]>h[i*2+1])
			{
				t=i*2+1;
			}
		}
		//假设发现最小的结点编号不是自己,说明子结点中有比父节点更小的值 
		if(t!=i)
		{
			swap(t,i);//交换他们。注意swap函数 
			i=t;//更新i为刚才与它交换的儿子结点的编号。便于接下来继续向下调整 
		}
		else
		{
			flag=1;
			//否则说明当前的父结点已经比俩个子结点都要小了,不须要再进行调整 
		}
	}	
} 
//建立堆函数 
void creat()
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		//总最后一个非叶结点到第一个结点一次进行向上调整 
		siftdown(i);
	}
}
//删除最大的元素 
int deletemax()
{
	int t;
	t=h[1];//用一个暂时变量记录堆顶点的值 
	h[1]=h[n];//将堆的最后一个点赋值给堆顶 
	n--;//堆的元素降低1 
	siftdown(1);//向下调整 
	return t;//返回之前记录的堆的顶点的最大值 
}
int main()
{
	int i,num;
	scanf("%d",&num);
	for(i=1;i<=num;i++)
	{
		scanf("%d",&h[i]);
	}
	n=num;
	creat();
	for(i=1;i<=num;i++)
	{//删除顶部元素,连续删除n次,事实上也就是从大到小的把数输出 
		printf("%d ",deletemax());
	}
	return 0;
}
代码,2:
#include<stdio.h>
int h[101]; //用来存储堆的数组
int n;//用来存储堆中的元素的个数,也就是堆的大小
//交换函数,用来交换堆中的俩个元素的值
void swap(int x,int y)
{
	int t;
	t=h[x];
	h[x]=h[y];
	h[y]=t;
} 
//向下调整函数 
void siftdown(int i)
{//传入一个须要向下调整的的节点编号i,这里传入1,即从堆的顶点開始向下调整 
	int t,flag=0;//flag用来标记是否须要继续向下调整
	//当i节点有儿子(事实上是至少有左儿子)而且有须要继续调整的时候循环就运行 
	while(i*2<=n&&flag==0)
	{
		//首先推断它与左儿子的关系,而且t记录值比較小的节点编号 
		if(h[i]<h[i*2])
		{
			t=i*2;
		}
		else
	    {
	    	t=i;
		}
		//假设它有右儿子。再对右儿子进行讨论 
		if(i*2+1<=n)
		{
			//假设右儿子的值更大,更新较小的节点编号 
			if(h[t]<h[i*2+1])
			{
				t=i*2+1;
			}
		}
		//假设发现最小的结点编号不是自己,说明子结点中有比父节点更小的值 
		if(t!=i)
		{
			swap(t,i);//交换他们,注意swap函数 
			i=t;//更新i为刚才与它交换的儿子结点的编号。便于接下来继续向下调整 
		}
		else
		{
			flag=1;
			//否则说明当前的父结点已经比俩个子结点都要小了,不须要再进行调整 
		}
	}	
} 
//建立堆函数 
void creat()
{
	int i;
	for(i=n/2;i>=1;i--)
	{
		//总最后一个非叶结点到第一个结点一次进行向上调整 
		siftdown(i);
	}
}
//堆排序
void heapsort()
{
	while(n>1)
	{
		swap(1,n);
		n--;
		siftdown(1);
	}
 } 
 int main()
 {
 	int i,num;
 	scanf("%d",&num);
 	for(i=1;i<=num;i++)
 	{
 		scanf("%d",&h[i]);
	}
	n=num;
	creat();//建堆
	heapsort();//堆排序
	for(i=1;i<=num;i++)
	{
		printf("%d ",h[i]);
	 } 
	 return 0;
 }



建堆,以及对堆排序

标签:let   can   自己   lag   amp   最大   ret   max   sort   

原文地址:http://www.cnblogs.com/lytwajue/p/6795368.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!