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

建堆,以及对堆排序

时间:2015-08-13 12:09:32      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

                                        建堆,以及堆排序

代码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;
 }



版权声明:本文为博主原创文章,未经博主允许不得转载。

建堆,以及对堆排序

标签:

原文地址:http://blog.csdn.net/qq_16997551/article/details/47609481

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