Dev.C++树的基础:树是一个有n个点n-1条边的稀疏图,所以树就是用链式前向星存储。
链式前向星的结构和链表相似(谁让它是链式的)
那么链式前向星是什么呢
是这个
int head[maxn],w[maxn],cnt=0;
struct edge
{
int to,nxt;
}e[maxn];
变量解释
head[i]: 以i为起点的插入的最后一条边(或是搜索的第一条边)
nxt[i]: i的链域
to[i]: i所指向的点
w[i]: i的点权/边权
cnt:你猜有啥用
然后就是插入动作了。
void add(int u,int v)//插入一条边使得u指向了v
{
e[++cnt].to=v;//u所指向的是v
e[cnt].nxt=head[u];//在u之前插入的边
head[u]=cnt;//更新在u之前插入的边(即下一个u插入之前插入的边,就是cnt,这句话可能有点绕,自行理解)
}
那么,cnt指的就是插入的第cnt条边了。
到此为止,树的存储就完了。
for(int i=head[u];i!=0;i=e[i].nxt)
树的遍历
只需要一个for,结合上面树的存储看,我相信你能看懂。
我看不懂!
去去去,怎么可能看不懂!
既然看不懂,那我还是解释一下吧。谁让我那么帅
从你要遍历的点开始,将他的每个点都遍历一遍就可以了。
按照链表的思想,从父亲开始,顺着链域跑一边就可以了。
有人说:哪有那么简单!你这只跑了他的儿子节点!
再来一个dg就OK了嘛。
实际上,在图论中,用链式前向星存图,可以根据自己的需要使用递归或循环来遍历整一个图。下面是树的遍历模式。
void tree(int u)
{
if(u>n)return;
for(int i=head[u];i!=0;i=e[i].nxt)tree(e[i].to);
}
所以,数的基础操作并不难,将链式前向星理解了就很简单,要背的话……
参考树状数组倒数第二句话。