今天由于有测试
就浅学树,以及堆排序
以及对并查集的学习
以下是对于堆排序的代码实现
#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;
}