森林和二叉树的转换

一、树的存储结构

1.双亲表示法

  假设以一组连续空间存储树的结点,同时在每个结点中附近一个指示器指示其双亲结点在链表的位置

#define MAXSIZE 100
typedef struct PTNode{//结点结构
TElemType data;
int parent;
}PTNode;
typedef struct{
PYNode nodes[MAXSIZE];
int r,n;//根的位置和结点数
}PTree;

这种存储结构利用每个结点(除了根结点外)只有唯一双亲的性质。反复利用PARENT(T,x)操作,直到遇见无双亲结点时便找到了树的根,但是在这种表示方法中,求结点的孩子遍历整个结构。

由于根结点是没有双亲的,约定根结点的位置位置域为-1.,根据结点的parent指针很容易找到它的双亲结点。所用时间复杂度为O(1),直到parent为-1时,表示找到了树结点的根。

2.孩子表示法

 数据结构(P136页)

由于树中每个结点可能有多棵树,则可用多重链表,即每个结点有多个指针域,其中每个指针指向一棵子树的根结点

把每个结点的还结点排列起来,看成一个线性表,且以单链表作为存储结构,则n个结点有n个孩子链表(叶子的孩子链表位空表)。而n个头指针又组成一个线性表,为了便于查找,可采用顺序存储结构。

 

typedef struct CTNode{//孩子结点
    int child;
    struct CTNode *next;
}ChildPtr;
typedef struct{
    TElemType data;
  //int parent;双亲孩子表示法的存储需加上这条 ChildPtr firstchild;
//孩子链表头结点 }CTBox; typedef struct{ CTBox node[MAXSIZE]; int n,r;//结点数和根的位置; }CTree;

3.孩子兄弟表示法

又称二叉树表示法或二叉链表表示法,即以二叉链表作为树的存储结构。链表中结点的两个链域分别指向该结点的第一个孩子结点和下一个兄弟结点,分别为firstchild域和nextsibling域

typedef struct CNode{
    ElemType data;
    struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;

 该种存储结构便于实现个各种树的操作。首先易于实现找结点孩子等的操作。例如若要访问结点x的第i个孩子,则只要先从firstchild域找到第一个孩子,然后沿着孩子结点的nextsibling域连续走i-1步。便可找到x的第i个孩子结点。当然,如果为每个结点增设一个PAARENT域,则同样能方便实现PARENT(T,x)操作。

二、树转换为二叉树

树转换为二叉树

(1)加线。在所有兄弟结点之间加一条连线。

(2)去线。树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线。

(3)层次调整。以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明。(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子)

森林转换为二叉树

(1)把每棵树转换为二叉树。

(2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来。

猜你喜欢

转载自www.cnblogs.com/wuhenxiansen/p/10422941.html