树(3)--树和森林

一:树的存储结构


1.双亲表示法:

    每个节点都存储它的双亲结点的位置:

#define MAX_TREE_SIZE 100   
typedef struct PTNode {   //结点结构 
   Elem data;
   int parent;   // 双亲位置域
} PTNode;
typedef struct {   //树结构  
  PTNode nodes[MAX_TREE_SIZE];
  int r, n;    // 根结点的位置和结点个数
} PTree;
这种结构优点很明显是可以容易找到结点的双亲,缺点时找孩子结点不方便,需要从下往上遍历整个树!

2.孩子表示法:

  

  (1).第一种结构就是所有结点结构全部一样,即每个结点都有同等数量指向它的孩子结点的指针,这样明显会造成空间的浪费;

  (2).第二种就是结点的结构不一样,即degree不一样(所以dy不一样),空间倒是节省了,但是操作不方便。

 

因此我们看能不能寻找一种比较好的方式,可以节省空间也可以操作方便呢?

可以这样,让每个结点的所有孩子结点组成一个单链表(叶子结点的单链表为空),这样的话就节省了空间;

                    让每个单链表的头指针组成一个线性表(顺序存储),这样的话就节省了时间。

存储结构如下:

typedef struct CTNode {   //孩子结点
    int child;
   struct CTNode *next; 
} *ChildPtr;
typedef struct {  //双亲结点结构
    Elem data; 
    ChildPtr firstchild; // 孩子链的头指针
} CTBox;
typedef struct {  //树结构:
    CTBox nodes[MAX_TREE_SIZE];
    int n, r; // 结点数和根结点的位置    
} CTree;

当然,我们为了可以查找结点的双亲,可以在CTBox里面添加int parent结构:


3.孩子兄弟表示法:

    即每个结点设置两个指针,一个指向它的第一个孩子结点,第二个指向它的下一个兄弟结点

typedef struct CSNode  {
       Elem data;
       struct CSNode *firstchild ,
                     *nextsibling;
} CSNode, *CSTree;
这种结构很明显方便查找结点的孩子兄弟结点,我们同样可以设置一个指向双亲的指针,让其也可以查找双亲!


二.树和森林转二叉树

1.树和二叉树的转换.

       由于二叉树和树都可用二叉链表作为存储结构,则以二叉链表作为媒介可导出树与二叉树之间的一个对应关系。


          看图已经很明显了,我们可以把树转为它对应的孩子兄弟存储结构来表示,然后按照这个结构,用基本的二叉树的链式结构来理解,就可以转为二叉树了,相反把二叉树转为树也是一样的道理。

2.森林和二叉树的转换.

         从树的二叉链表表示的定义可知,任何一棵和树对应的二叉树,其右子树必空。 若把森林中第二棵树的根结点看成是第一棵树的根结点的兄弟,则同样可导出森林和二叉树的对应关系。


              同样咱们看图可以知道森林转二叉树就是把森林的各个树都转为对应的二叉树,然后把这些二叉树的树根相连就成了!     同理,二叉树转森林的道理就不想写了,自己看图吧!!!


三.树和森林的遍历:

1. 树的遍历:
                1)先根(序)遍历:若树不空,则先访问根结点,
                                                    然后依次先根遍历各棵子树。
                2)后根(序)遍历:若树不空,则先依次后根遍历
                                                    各棵子树,然后访问根结点。
                3)按层次遍历:  若树不空,则自上而下自左至
                                                    右访问树中每个结点。

2.森林的遍历:

            先序遍历(对森林中的每一棵树进行先根遍历)
                        1)若森林不空,访问森林中第一棵树的根结点;
                        2)先序遍历森林中第一棵树的子树森林;
                        3)先序遍历森林中(除第一棵树外)其余树构成的森林。
            后序遍历(对森林中的每一棵树进行后根遍历)
                        1)若森林不空,后序遍历森林中第一棵树的子树森林;
                        2)访问森林中第一棵树的根结点;
                        3)后序遍历森林中(除第一棵树外)其余树构成的森林。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值