多叉树(左孩子右兄弟)详细实现
多叉树定义
有一个根节点多个孩子结点(不止2个孩子结点)
相比于二叉树,只需要写一个结构体,在结构体中添加parent,left,right就可以表示整颗树,但是多叉树有多个孩子结点,无法仅用左右孩子做到!
怎么做呢?
我们利用"左孩子""右兄弟"的定义方法实现多叉树! 我们仍然用一个结构体实现,结构体中仍然是parent,left,right,只不过定义与二叉树不同! 在多叉树中left定义为:一个结点的最左边的孩子结点! 在多叉树中right定义为:一个结点的相邻右侧的兄弟结点!
图示:
结点深度问题(递归实现)
在递归算法中,我们传入结点u,以及深度p,用一个D[i]数组表示i号结点的深度 每次先看u的右兄弟是否存在,如果存在递归调用u.right,传入的深度p不变 如果u的右兄弟不存在,我们调用u.left看u的左孩子是否存在,传入深度p+1! (顺序可以改变,先看左孩子,再看右兄弟也可!)
实现代码
void fd(int u,int p)
{
D[u]=p;
if(T[u].r!=NUL) fd(T[u].r,p);
if(T[u].l!=NUL) fd(T[u].l,p+1);
}
递归树图解:(按先右兄弟,在左孩子顺序实现)
递归求深度复杂度分析
用递归求深度只需要将各个结点遍历一遍所以复杂度为O(n)
整体代码实现
输入n,总结点数 依次输入结点id,结点的度k,子结点c1,c2,…(有几个子结点,度就为多少) 13 0 3 1 4 10 1 2 2 3 2 0 3 0 4 3 5 6 7 5 0 6 0 7 2 8 9 8 0 9 0 10 2 11 12 11 0 12 0
输出结点信息
#include <bits/stdc++.h>
using namespace std;
const int NUL=-1;
const int maxn=1e5+10;
int n,id,k,c;
struct node
{
int p,l,r;
} T[maxn];
int D[maxn];
void init()
{
for(int i=0; i<n; i++)
{
T[i].l=T[i].p=T[i].r=NUL;
}
}
void fd(int u,int d)
{
D[u]=d;
if(T[u].r!=NUL) fd(T[u].r,d);
if(T[u].l!=NUL) fd(T[u].l,d+1);
}
//打印结点信息
void print(int u)
{
cout<<" node"<<u<<": parent = "<<T[u].p<<", depth = "<<D[u];
if(T[u].p==NUL)
{
cout<<" ,root, [";
}
else if(T[u].l==NUL)
{
cout<<" ,leaf, [";
}
else
{
cout<<" ,internal node, [";
}
for(int i=0,c=T[u].l;c!=NUL;i++,c=T[c].r)
{
if(i)cout<<", ";
cout<<c;
}
cout<<"]"<<endl;
}
int main()
{
cin>>n;
init();//初始化
int left,parent;
//读入结点信息
for(int i=0; i<n; i++)
{
cin>>id>>k;
for(int j=0; j<k; j++)
{
cin>>c;
if(j==0)
{
T[id].l=c;
}
else
{
T[left].r=c;
}
left=c;
T[c].p=id;
}
}
for(int i=0; i<n; i++)
{
if(T[i].p==NUL)
{
parent=i;
break;
}
}
fd(parent,0);//递归求深度
for(int i=0; i<n; i++)//打印n个结点的子节点
{
print(i);
}
return 0;
}
下一篇:
数据结构树-->树基础
