if(a[x].rchild!
=0)inorder(a[x].rchild);//递归生成右子树
}
十七、并查集
intgetfather(intx)//非递归求X结点的根结点的编号
{while(x!
=father[x])
x=father[x];
returnx;
}
intgetfather(intx)//递归求X结点的根结点的编号
{if(x==father[x])returnx;
elsereturngetfather(father[x]);
}
intgetfather(intx)//非递归求X结点的根结点编号同时进行路径压缩
{intp=x;
while(p!
=father[p])//循环结束后,P即为根结点
p=father[p];
while(x!
=father[x])//从X结点沿X的父结点进行路径压缩
{inttemp=father[x];//暂存X没有修改前的父结点
father[x]=p;//把X的父结点指向P
x=temp;
}
returnp;
}
intgetfather(intx)//递归求X结点的根结点编号同时进行路径压缩
{if(x==father[x])returnx;
else{
inttemp=getfather(father[x]);
father[x]=temp;
returntemp;
}
}
voidmerge(intx,inty)//合并x,y两个结点
{intx1,x2;
x1=getfather(x);//取得X的父结点
x2=getfather(y);//取得Y的父结点
if(x1!
=x2)father[x1]=x2;//两个父结点不同的话就合并,注意:
合并的是X,Y两个结点的根。
}
十八、Prime算法
voidprime(void)//prim算法求最小生成树,elist[i]是边集数组,a[i][j]为的权值。
edge为结构体类型。
{for(inti=1;i<=n-1;i++)//初始化结点1到其它n-1个结点形成的边集
{elist[i].from=1;
elist[i].to=i+1;
elist[i].w=a[1][i+1];
}
for(inti=1;i<=n-1;i++)//依次确定n-1条边
{intm=i;
for(intj=i+1;j<=n-1;j++)//确定第i条边时,依次在i+1至n-1条边中找最小的那条边
if(elist[j].wif(m!
=i)//如果最小的边不是第i条边就交换
{edgetmp=elist[i];elist[i]=elist[m];elist[m]=tmp;}
for(intj=i+1;j<=n-1;j++)//更新第i+1至n-1条边的最小距离。
{if(elist[j].w>a[elist[i].to][elist[j].to])elist[j].w=a[elist[i].to][elist[j].to];}
}
for(inti=1;i<=n-1;i++)//求最小生成树的值
ans=