每日总结 1.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)
{
	int t,flag=0;
	while(i*2<=n&&flag==0)
	{
		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);
			i=t;
		}
		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--;
	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++)
	{
		printf("%d ",deletemax());
	}
	getchar();
	getchar();
	return 0;
}

对于堆排序,有几个值得注意的点,堆排序有分为两种,一种为最大堆,一种为最小堆,顾名思义最大堆是树根部位为最大值的数(树)堆,而最小堆就相反。

另外给树增加一个新的值,就从树的末尾加入,并且与上面一个树相比较最大堆则比父结点大则两者相换位,小则不需要,最小堆与之相反。

对于建立堆则是直接建立一个数组再以树的性质对其进行自上而下的重新排序。

一道擒贼先擒王

即对查并集的学习

 

 

代码如下

#include<stdio.h>
int f[1000]={0},n,m,k,sum=0;
void init()//初始化
{
	int i;
	for(i=1;i<=n;i++)
	{
		f[i]=i;
	}
}
int getf(int v)
{
	if(f[v]==v)
	{
		return v;
	}
	else
	{
		f[v]=getf(f[v]);//找到头头
		return f[v];
	}
}
void merge(int v,int u)
{
	int t1,t2;
	t1=getf(v);
	t2=getf(u);
	{
		if(t1!=t2)
		{
			f[t2]=t1;
		}
	}
}
int main()
{
	int i,x,y;
	scanf("%d%d",&n,&m);
	init();
	for(i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		merge(x,y);
	}
	for(i=1;i<=n;i++)
	{
		if(f[i]==i)
		{
			sum++;
		}
	}
	printf("%d\n",sum);
	getchar();
	getchar();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值