树和森林
1.双亲表示法
#define MAX_TREE_SIZE 100 //树中最多结点
typedef struct{ //树的节点定义
ElemType data;
int parent; //双亲位置域
}PTNode;
typedef struct{ //树的类型定义
PTNode nodes[MAX_TREE_SIZE]; //双亲表示
int n; //节点数
}PTree;
2.孩子表示法
孩子表示法是将每个节点的孩子节点都用单链表链接起来形成一个线性结构,此时n个节点就有n个孩子链表(叶子节点的孩子链表为空表)
3.孩子兄弟表示法
typedef struct CSNode{
ElemType data;
struct CSNode *firstchild,*nextsibling; //第一个孩子和右兄弟指针
}CSNode,*CSTree;
这种存储表示法比较灵活,最大有点是可以方便地实现树转换为二叉树的操作,易于查找节点的孩子等,但缺点是从当前节点查找双亲节点比较麻烦,若为每个节点增加一个parent域指向其父节点,则查找节点的父节点也很方便。
P175 树和森林
1.求以孩子兄弟表示法存储的森林的叶子节点数
//若节点没有孩子(firstchild=null),则它必是叶子
//总叶子数=孩子子树上的叶子数+兄弟子树上的叶子数
int countLeafNode(CSTree T){
if(T){
if(!T->firstchild)
return 1+countLeafNode(T->nextsibling); //返回叶子节点和其兄弟子树中的叶子节点数
else //返回孩子子树和兄弟子树中叶子树之和
return countLeafNode(T->firstchild)+countLeafNode(T->nextsibling);
}
return 0;
}
2.以孩子兄弟链表为存储,设计递归算法求树的深度
//若采用非递归,则思想与二叉树和线索二叉树中T2类似
int computeDepth(CSTree T){
if(T){
int leftDepth=1+computeDepth(T->fistchild); //孩子树的高
//这里不+1是因为右兄弟是另一棵树,故应重新开始计算
int rightDepth=computeDepth(T->nextsibling); //兄弟树的高
return (leftDepth>=rightDepth)?leftDepth:rightDepth;
}
return 0;
}
3.已知一棵树的层次序列及每个节点的度,构造此树的孩子兄弟链表
void createCSTree(CSTree &T,DataType e[],int degree[],int n){
//e是参差序列,degree是各节点的度,n是树的节点个数
CSNode *pointer=new CSNode[MAXNODES];
int k=0;
for(int i=0;i<n;i++){
//初始化
pointer[i]->data=e[i];
pointer[i]->firstchild=pointer[i]->nextsibling=null;
int d=degree[i]; //节点i的度数
if(d){
k++; //子女节点序号
pointer[i]->firstchild=pointer[k]; //建立i与孩子的连接
for(int j=1;j<d;j++){ //建立兄弟间的连接
k++;
pointer[k-1]->nextsibling=pointerp[k];
}
}
}
T=pointer[0];
delete[] pointer;
}