1.加线:在全部兄弟结点之间加一条连线 2.去线:对树中每一个结点,只保留他与第一个长子结点的连线,删除他与其余孩子结点之间的连线 3.层次调整。以树的根节点为轴心,将整棵树顺时针旋转必定角度,使结构井井有条。 注意:第一个孩子是二叉树结点的左孩子,兄弟转换过来的孩子是结点的右孩子
转换后,根节点只有左子树,最左侧链表不改变
1.将每一个树转换为二叉树 2.第一棵二叉树不动,从第二棵二叉树开始,依次吧后一棵二叉树的根节点做为前一棵二叉树的根节点的右子树,用线链接起来。当全部的二叉树链接起来,就获得了由森林转换而来的二叉树
1.若某结点的左孩子存在,则将该左孩子的右孩子结点,以及该左孩子的右孩子的右孩子结点,以及...,就是左孩子的n个右孩子结点都做为此结点的孩子。将该结点与这些右孩子结点用线链接 2.去线:删除原二叉树中全部结点与其右孩子结点的连线
咱们从一:知道树转二叉树只有左子树,森林转二叉树会同时存在左子树和右子树
因此判断一棵树可以转换为一棵树仍是一个森林,就看这个二叉树的根节点有没有右孩子
1.从根节点开始,如果右孩子存在,将右链拆开,全部的右孩子连线都删除。获得分离的二叉树。
2.再将每棵分离后的二叉树转换为树便可
先根遍历树,即先访问树的根节点,而后依次先根遍历根的每棵子树(相似于先序遍历)
后根遍历,即先依次后根遍历每棵子树,而后再访问根节点。(相似于后序遍历)
先访问森林的第一棵树的根节点,而后依次先根遍历....,再依次用一样方法遍历下一棵树....
先访问森林的第一棵树的根节点,而后依次后根遍历....,再依次用一样方法遍历下一棵树....
树,森林的前根(序)遍历和二叉树的前序遍历结果相同,树,森林的后根(序)遍历和二叉树的中序遍历结果相同
能够根据(一)和(二)轻松推出结论,而后利用这种规律,解决这些复杂的树,森林遍历问题
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> typedef char TElemType;//树的孩子兄弟表示法结构定义 typedef struct TNode //结点结构 { TElemType data; //结点数据 struct TNode *lchild, *rsibling; //左孩子,右兄弟指针 }TNode, *Tree; //二叉树的二叉链表结点结构定义 typedef struct BiTNode //结点结构 { TElemType data; //结点数据 struct BiTNode *lchild, *rchild; //左右孩子指针 }BiTNode, *BiTree; //使用孩子兄弟法建立一棵树 //建立一棵树ABDG#H#I###CEJ##F#### void createTree(Tree *T) { TElemType ch; scanf("%c", &ch); if (ch == '#') *T = NULL; else { *T = (Tree)malloc(sizeof(TNode)); (*T)->data = ch; createTree(&(*T)->lchild); //构造左孩子 createTree(&(*T)->rsibling);//构造右兄弟 } } void Tree2BiTree(Tree T,BiTree *BT) { if (T) { *BT = (BiTree)malloc(sizeof(BiTNode)); (*BT)->data = T->data; Tree2BiTree(T->lchild, &(*BT)->lchild); //利用对应的结点来构造二叉树 Tree2BiTree(T->rsibling, &(*BT)->rchild); } else *BT = NULL; } //传入的是转换为二叉树的树 void PreOrderTraverseForTree(BiTree BT) { if (BT) { printf("%c", BT->data); PreOrderTraverseForTree(BT->lchild); PreOrderTraverseForTree(BT->rchild); } } int main() { Tree T; BiTree BT; createTree(&T); Tree2BiTree(T,&BT); PreOrderTraverseForTree(BT); system("pause"); return 0; }