第六章树.pptVIP

  • 6
  • 0
  • 约2.16万字
  • 约 87页
  • 2017-03-04 发布于天津
  • 举报
第六章树

* * * * * * * 先序遍历的非递归算法: 先序遍历的特点:先访问根,接着访问左子树,所以需要用栈保存右子树的信息 当左到不能再左去访问节点时,从栈中弹出节点继续访问 思想: -先压入一个空指针 –遇到一个结点,就访问该结点,并把此结点的非空右结点推入栈中,然后下降去遍历它的左子树; –遍历完左子树后,从栈顶弹出一个结点,遍历以此结点为根的子树 -整个过程直到栈顶为空指针为止 中序遍历:每棵树的左子树访问完了才访问根结点,再访问右子树,所以需要先将根结点入栈 思想: 遇到一个结点 –把它压入栈中 –遍历其左子树 ?遍历完左子树 ,从栈顶弹出该结点并访问之 ,接着按照其右链地址遍历该结点的右子树 后序: 由于需要访问完一个结点的左右子树之后才能访问它自己,所以需要一个标志标记该结点是访问完了左子树/访问完了右子树 因此需要给栈中每个元素加上一个特征位 :Left 表示已进入该结点的左子树, 将从左边回来/Right 表示已进入该结点的右子树, 将从右边回来 * * * if(!T) return FALSE; if(In(T-lchild)) return TRUE; if(T-data==x) return TRUE; return In(T-rchild); * * * 指针与线索的区分方法之二:不改变链结点的构造,而是在作为线索的地址前加一个负号,即“负地址”表示线索,“正地址”表示指针。 二叉树线索化的好处: 其实线索化二叉树等于将一棵二叉树转变成了一个双向链表,这为二叉树结点的插入、删除和查找带来了方便。 在实际问题中,如果所用的二叉树需要经常遍历或查找结点时需要访问结点的前驱和后继,则采用线索二叉树结构是一个很好的选择。 * * * * * * * * * * * * * * 研究:树转换为二叉树,没有下一个兄弟(右兄弟)的结点个数是非终端结点的个数+1 * * 先根遍历:先访问根结点,在依次访问根的 每棵子树 森林的先序遍历 * * * * * * * 贪心算法 * 压缩原理 * * * * * * * * * * * * * * * * * * * * * * * * * * * * 深度优先搜索和广度优先搜索 * * * * * data degree child1 child2 …… childd 或 E F G H I J B C X A 3 3 1 2 0 0 0 0 0 0 T J I H G F E A C X B typedef struct CTNode {int child; struct CTNode *next; }*ChildPtr; typedef struct { TElemType data; ChildPtr firstchild; //孩子链表头指针 }CTBox; typedef struct {CTBox nodes[MAX_TREE_SIZE]; int n,r; //结点数和根的位置 } 另一种结构: 0 1 2 3 4 5 6 7 8 9 双亲孩子法 (3)孩子兄弟法(二叉树表示法) 以二叉链表作为树的存储结构 firstchild data nextsibling typedef struct CSNode {ElemType data; struct CSNode *firstchild,*nextsibling; }CSNode, *CSTree; 表示二叉树的二叉链表与表示树的二叉链表结构相同,指针含义不同。 1.森林转换成二叉树 如果把森林中第二棵树的根结点看成是第一棵树的根结点的兄弟,把第三棵树的根结点看成是第二棵树根结点的兄弟,则可以把森林转化为二叉树 如果F={T1,T2,……,Tm}是森林,则可按如下规则转换成一棵二叉树B=(root,LB,RB),规则为: (1)若F为空,即m=0,则B为空树; (2)若F非空,即m?0,则B的根为ROOT(T1), B的左子树LB是从T1子树森林{T11,T12,……,T1m1}转换而成的二叉树; 其右子树RB是从森林F’={T2,T3,……,Tm}转换而成的二叉树 二、森林和树的转换 A C B D E F I J G H E F A C B D I J G H A C B D E F I J G H 森林 二叉树 如果 B=(root,LB,RB)是一棵二叉树, 则可按如下规则转换成森林F={T1,T2,…,Tn}: (1)若B为空,则 F为空; (2)若B非空, 则 F中第一棵树T1的根ROOT(T1)即为二叉树B的根root。T1根结点的子树森林F1是由B的

文档评论(0)

1亿VIP精品文档

相关文档