40
树树树树树树树 树树树 ( Binary Tree) 树树树树树树 树树树树树 ( Binary Tree Traversal) ( Heap ) 树树树树 ( Tree & Forest) 树树树树树树 树树树树 ( Huffman Tree)

树和森林的概念 二叉树 (Binary Tree) 二叉树的表示 二叉树遍历 (Binary Tree Traversal) 堆 ( Heap ) 树与森林 (Tree & Forest)

Embed Size (px)

DESCRIPTION

第六章 树与森林. 树和森林的概念 二叉树 (Binary Tree) 二叉树的表示 二叉树遍历 (Binary Tree Traversal) 堆 ( Heap ) 树与森林 (Tree & Forest) 二叉树的计数 霍夫曼树 (Huffman Tree). 树和森林的概念. 树的定义 树是由 n ( n  0) 个结点组成的有限集合。如果 n = 0 ,称为空树;如果 n > 0 ,则  有一个特定的称之为 根 (root) 的结点,它只有直接后继,但没有直接前驱; - PowerPoint PPT Presentation

Citation preview

Page 1: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

树和森林的概念二叉树 (Binary Tree)二叉树的表示二叉树遍历 (Binary Tree Traversal)堆 ( Heap )树与森林 (Tree & Forest)二叉树的计数霍夫曼树 (Huffman Tree)

Page 2: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

树和森林的概念树和森林的概念树的定义树的定义 树是由树是由 nn ( (nn 0) 0) 个结点组成的有限集合。个结点组成的有限集合。如果如果 nn = 0 = 0 ,称为空树;如果,称为空树;如果 nn > 0 > 0 ,则,则 有一个特定的称之为有一个特定的称之为根根 (root)(root) 的结点,的结点,它只有直接后继,但没有直接前驱;它只有直接后继,但没有直接前驱; 除根以外的其它结点划分为除根以外的其它结点划分为 mm ( (mm 0) 0)个互不相交的有限集合个互不相交的有限集合 TT00, , TT11, …, , …, TTmm-1-1 ,每个集,每个集合又是一棵树,并且称之为根的合又是一棵树,并且称之为根的子树子树 (subTree)(subTree) 。。每棵子树的根结点有且仅有一个直接前驱,但可每棵子树的根结点有且仅有一个直接前驱,但可以有以有 00 个或多个直接后继。个或多个直接后继。

Page 3: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

结点结点 (node)(node) 结点的度结点的度 (degree)(degree) 分支分支 (branch)(branch) 结点结点 叶叶 (leaf)(leaf) 结点结点 子女子女 (child)(child) 结点结点 双亲双亲 (parent)(parent) 结点结点

兄弟兄弟 (sibling)(sibling) 结点结点 祖先祖先 (ancestor)(ancestor) 结点结点 子孙子孙 (descendant)(descendant)

结点结点 结点所处层次结点所处层次 (level)(level) 树的高度树的高度 (depth)(depth) 树的度树的度 (degree(degree))

有序树有序树 无序树无序树 森林森林

Page 4: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

template <class Type> class Tree {public: Tree ( ); ~Tree ( ); position Root ( ); BuildRoot ( const Type& value ); position FirstChild ( position p ); position NextSibling ( position p, position v ); position Parent ( position p ); Type Retrieve ( position p ); position InsertChild ( const position p, const Type &value ); position DeleteChild ( position p, int i ); void DeleteSubTree ( position t ); int IsEmpty ( );}

树的抽象数据类型树的抽象数据类型

Page 5: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树 二叉树 (Binary Tre(Binary Tree)e)二叉树的定义二叉树的定义

二叉树的五种不同形态二叉树的五种不同形态

一棵二叉树是结点的一个有限集合,一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交两棵分别称为左子树和右子树的、互不相交的二叉树组成。的二叉树组成。

Page 6: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

性质性质 11 若二叉树的层次从若二叉树的层次从 00 开始开始 , , 则在二叉树则在二叉树的第 的第 i i 层最多有 层最多有 22i i 个结点。个结点。 ((ii 0) 0) [[ 证明用数学归纳法证明用数学归纳法 ]]

性质性质 22 高度为高度为 kk 的二叉树最多有 的二叉树最多有 22k+k+11-1-1 个结个结点。点。((kk -1) -1) [[ 证明用求等比级数前证明用求等比级数前 kk 项和的公式项和的公式 ]]

性质性质 33 对任何一棵二叉树对任何一棵二叉树 , , 如果其叶结点个数如果其叶结点个数为 为 nn00, , 度为度为 22 的非叶结点个数为 的非叶结点个数为 nn22, , 则有则有 nn00 == nn22 ++ 11

二叉树的性质二叉树的性质

Page 7: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

证明:证明:若设度为若设度为 11 的结点有的结点有 nn11 个,总结点个,总结点个数为个数为 nn ,总边数为,总边数为 ee ,则根据二叉树的,则根据二叉树的定义,定义, nn = = nn00 + + nn11 + + nn22 ee = 2 = 2nn22 + + nn1 1 = = nn - 1 - 1因此,有 因此,有 22 nn22 + + nn11 = = nn00 + + nn11 + + nn22 - 1 - 1 nn22 = = nn00 - 1 - 1 nn00 = = nn22 + 1 + 1

定义定义 11 满二叉树满二叉树 (Full Binary Tree)(Full Binary Tree) 定义定义 22 完全二叉树完全二叉树 (Complete Binary Tree)(Complete Binary Tree) 若设二叉树的高度为若设二叉树的高度为 hh ,则共有,则共有 hh+1+1 层。层。除第除第 hh 层外,其它各层层外,其它各层 (0(0hh-1)-1) 的结点数都达到的结点数都达到最大个数,第最大个数,第 hh 层从右向左连续缺若干结点,这层从右向左连续缺若干结点,这就是完全二叉树。就是完全二叉树。

Page 8: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

性质性质 44 具有具有 nn 个结点的完全二叉树的高度个结点的完全二叉树的高度为为 loglog22((nn+1)+1) --11证明:证明:设完全二叉树的高度为设完全二叉树的高度为 hh ,则有,则有 22hh -- 1 < 1 < nn 2 2hh+1+1 -- 1 2 1 2hh < < n+n+1 1 2 2hh+1+1 取对数 取对数 hh < log < log22((nn+1) +1) hh+1 +1

Page 9: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

性质性质 55 如果将一棵有如果将一棵有 nn 个结点的完全二叉树自个结点的完全二叉树自顶向下,同一层自左向右连续给结点编号顶向下,同一层自左向右连续给结点编号 0, 1, 2,0, 1, 2, …, …, nn-1-1 ,然后按此结点编号将树中各结点顺序,然后按此结点编号将树中各结点顺序地存放于一个一维数组中地存放于一个一维数组中 , , 并简称编号为并简称编号为 ii 的结的结点为结点点为结点 i i (0 (0 i i nn-1-1 。则有以下关系: 。则有以下关系: 若若 i == i == 0, 0, 则 则 i i 无双亲无双亲 若若 i i > 0, > 0, 则 则 i i 的双亲为的双亲为 ((i i -1)/2-1)/2 若若 2*2*ii+1 <+1 < n n, , 则 则 i i 的左子女为的左子女为 2*2*ii+1+1 若若 2*2*ii+2 < +2 < nn, , 则 则 i i 的右子女为的右子女为 2*2*ii+2+2 若 若 i i 为偶数为偶数 , , 且且 ii != 0, != 0, 则其左兄弟为则其左兄弟为 ii-1-1 若 若 i i 为奇数为奇数 , , 且且 ii != != nn-1, -1, 则其右兄弟为则其右兄弟为 ii++11 i i 所在层次为 所在层次为 loglog2 2 ((ii+1)+1)

Page 10: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树的抽象数据类型二叉树的抽象数据类型template <class Type> class BinaryTree {public: BinaryTree ( ); BinaryTree ( BinTreeNode<Type> * lch, BinTreeNode<Type> * rch, Type item ); int IsEmpty ( ); BinTreeNode<Type> *Parent ( ); BinTreeNode<Type> *LeftChild ( ); BinTreeNode<Type> *RightChild ( ); int Insert ( const Type &item ); int Find ( const Type &item ) const; Type GetData ( ) const; const BinTreeNode<Type> *GetRoot ( ) const;}

Page 11: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

完全二叉树的数组表示 一般二叉树的数组表示

二叉树的表示二叉树的表示数组表示数组表示

Page 12: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

单支树

由于一般二叉树必须仿照完全二叉树那样存由于一般二叉树必须仿照完全二叉树那样存储,可能会浪费很多存储空间,单支树就是储,可能会浪费很多存储空间,单支树就是一个极端情况。一个极端情况。

Page 13: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

链表表示链表表示

Page 14: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树链表表示的示例

Page 15: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉链表的静态结构

Page 16: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

template <class Type> class BinaryTree;

template <class Type> Class BinTreeNode {friend class BinaryTree;public: BinTreeNode ( ) : leftChild (NULL), rightChild (NULL) { } BinTreeNode ( Type item, BinTreeNode<Type> *left = NULL,

BinTreeNode<Type> *right = NULL ) : data (item), leftChild (left), rightChild (right) { } const Type & GetData ( ) const { return data; }

二叉树的类定义二叉树的类定义

Page 17: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

BinTreeNode<Type> *GetLeft ( ) const { return leftChild; } BinTreeNode<Type> *GetRight ( ) const { return rightChild; } void SetData ( const Type & item ) { data = item; } void SetLeft ( BinTreeNode <Type> *L ) { leftChild = L; } void SetRight ( BinTreeNode <Type> *R ) { rightChild = R; }private: BinTreeNode<Type> *leftChild, *rightChild; Type data;};

Page 18: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

template <class Type> class BinaryTree {public: BinaryTree ( ) : root (NULL) { } BinaryTree ( Type value ) : RefValue (value), root (NULL) { } virtual ~BinaryTree ( ) { destroy ( root ); } virtual int IsEmpty ( ) { return root == NULL ? 1 : 0; } virtual BinTreeNode <Type> *Parent ( BinTreeNode <Type> *current ) { return root == NULL || root == current ? NULL : Parent ( root, current ); }

Page 19: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

virtual BinTreeNode <Type> *LeftChild ( BinTreeNode <Type> *current ) { return root != NULL ? current→leftChild : NULL; } virtual BinTreeNode <Type> *RightChild ( BinTreeNode <Type> *current ) { return root != NULL ? current→rightChild : NULL; } virtual int Insert ( const Type & item); virtual int Find ( const Type &item ) const; const BinTreeNode <Type> *GetRoot ( ) const { return root; } friend istream &operator >> ( istream &in, BinaryTree<Type> &Tree )

Page 20: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

friend ostream &operator << ( ostream &out, BinaryTree <Type> &Tree )private: BinTreeNode <Type> *root; Type RefValue; BinTreeNode <Type> *Parent ( BinTreeNode <Type> *start, BinTreeNode <Type> *current ); int Insert ( BinTreeNode<Type> * &current, const Type &item ) void Traverse ( BinTreeNode<Type> *current, ostream &out ) const int Find ( BinTreeNode<Type> *current, const Type &item ) constvoid destroy(BinTreeNode<Type> *current);}

Page 21: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树部分成员函数的实现二叉树部分成员函数的实现

template<class Type> void BinaryTree<Type>:: destroy ( BinTreeNode<Type> *current ) { if ( current != NULL ) { destroy ( current→leftChild ); destroy ( current→rightChild ); delete current; }}

Page 22: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

Template <class Type> BinTreeNode <Type> *BinaryTree <Type>::Parent ( BinTreeNode <Type>*start, BinTreeNode <Type> *cuurent ) { if ( start == NULL ) return NULL; if ( start→leftChild == current || start→rightChild == current ) return start; BinTreeNode <Type> *p; if ( ( p = Parent ( start→leftChild, current ) ) != NULL ) return p; else return Parent ( start→rightChild, current );}

Page 23: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

Template <class Type> void BinaryTree<Type>::Traverse ( BinTreeNode <Type> *current, ostream &out ) const { if ( current != NULL ) { out << current→data << ‘ ’; Traverse ( current→leftChild, out );

Traverse ( current→rightChild, out ); }}

Page 24: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

Template <class Type> istream & operator >> ( istream & in, BinaryTree <Type> &Tree ) { Type item; cout << " 构造二叉树 :\n "; cout << " 输入数据 ( 用 " << Tree.RefValue << " 结束 ): "; in >> item; while ( item != Tree.RefValue ) {

Tree.Insert ( item ); cout << " 输入数据 ( 用 " << Tree.RefValue << " 结束 ): "; in >> item; } return in;}

Page 25: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

Template <class Type> ostream & operator << ( ostream & out, BinaryTree <Type> &Tree ) { out << “ 二叉树的前序遍历 .\n"; Tree.Traverse ( Tree.root, out ); out << endl; return out;}

Page 26: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

6.3 6.3 遍历二叉树遍历二叉树 (Binary Tree Travers(Binary Tree Traversal)al) 所谓遍历二叉树,就是按某种次序访所谓遍历二叉树,就是按某种次序访问树中的结点,要求每个结点访问一次且仅访问树中的结点,要求每个结点访问一次且仅访问一次。问一次。 设设访问根结点访问根结点记作 记作 VV 遍历根的左子树遍历根的左子树记作 记作 LL 遍历根的右子树遍历根的右子树记作 记作 RR 则可能的遍历次序有则可能的遍历次序有 前序 前序 VLR VLR 镜像 镜像 VRVRLL 中序 中序 LVR LVR 镜像 镜像 RRVLVL 后序 后序 LRV LRV 镜像 镜像 RRLVLV

Page 27: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

中序遍历二叉树算法的框架是:中序遍历二叉树算法的框架是: 若二叉树为空,则空操作;若二叉树为空,则空操作; 否则否则

中序遍历左子树 中序遍历左子树 (L)(L) ;; 访问根结点 访问根结点 (V)(V) ;; 中序遍历右子树 中序遍历右子树 (R)(R) 。。

遍历结果遍历结果 aa + + bb * * cc -- dd -- ee / / ff

中序遍历 中序遍历 (Inorder Travers(Inorder Traversal)al)

表达式语法树表达式语法树

Page 28: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树递归的中序遍历算法二叉树递归的中序遍历算法emplate <class Type> void BinaryTree <Type>::InOrder ( ) { InOrder ( root );}template <class Type> void BinaryTree <Type>:: InOrder ( BinTreeNode <Type> *current ) { if ( current != NULL ) { InOrder ( current→leftChild ); cout << current→data; InOrder ( current→rightChild ); }}

Page 29: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

中序遍历二叉树的递归过程图解中序遍历二叉树的递归过程图解

Page 30: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

前序遍历 前序遍历 (Preorder Traversal)(Preorder Traversal)前序遍历二叉树算法的框架是前序遍历二叉树算法的框架是 若二叉树为空,则空操作;若二叉树为空,则空操作; 否则否则

访问根结点 访问根结点 (V)(V) ;; 前序遍历左子树 前序遍历左子树 (L)(L) ;; 前序遍历右子树 前序遍历右子树 (R)(R) 。。

遍历结果遍历结果

-- + + aa * * bb -- c dc d / / e fe f

Page 31: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树递归的前序遍历算法二叉树递归的前序遍历算法template <class Type>void BinaryTree <Type>::PreOrder ( ) { PreOrder ( root );}

template <class Type> void BinaryTree<Type>:: PreOrder ( BinTreeNode <Type> *current ) { if ( current != NULL ) { cout << current→data; PreOrder ( current→leftChild ); PreOrder ( current→rightChild ); }}

Page 32: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

后序遍历 后序遍历 (Postorder Travers(Postorder Traversal)al)后序遍历二叉树算法的框架是后序遍历二叉树算法的框架是 若二叉树为空,则空操作;若二叉树为空,则空操作; 否则否则

后序遍历左子树 后序遍历左子树 (L)(L) ;; 后序遍历右子树 后序遍历右子树 (R)(R) ;; 访问根结点 访问根结点 (V)(V) 。。

遍历结果遍历结果

a b c da b c d -- * + * + e fe f / / --

Page 33: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

二叉树递归的后序遍历算法template <class Type> void BinaryTree <Type>::PostOrder ( ) { PostOrder ( root );}

template <class Type> void BinaryTree<Type>::PostOrder ( BinTreeNode <Type> *current ) { if ( current != NULL ) { PostOrder ( current→leftChild ); PostOrder ( current→rightChild ); cout << current→data; }}

Page 34: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

1 、利用二叉树后序遍历计算二叉树结点个数及二叉树的高度

template <class Type> int BinaryTree<Type>::Size ( const BinTreeNode <Type> *t ) const { if ( t == NULL ) return 0; else return 1 + Size ( t→leftChild ) + Size ( t→rightChild );}

template <class Type> int BinaryTree<Type>::Height ( const BinTreeNode <Type> *t ) const {

6.3.2 6.3.2 应用二叉树遍历的事应用二叉树遍历的事例例

Page 35: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

if ( t == NULL ) return -1; else return 1 + Max ( Height ( t→leftChild ), Height ( t→rightChild ) );}

6.3 .3 6.3 .3 遍历二叉树的非递归算法遍历二叉树的非递归算法

Page 36: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

Template <class type> void BinaryTree<Type>::PreOrdere () { Stack<Treenode<Type> * > st; BinTreeNode<type> * p=root; do{ while ( p ! =NULL) { cout( p→data ); S.Push( p); p=p→leftchild; } if ( st.IsEmpty()=0 ){ p = S.getTop( ); st.Pop( ); p=p->rightchild } // 进右子树 } }while (p!=NULL||!st.Isempty())}

11 、利用栈的前序遍历非递归算法、利用栈的前序遍历非递归算法

Page 37: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

22 、利用栈的中序遍历非递归算法、利用栈的中序遍历非递归算法void InOrderTraverse ( Bitree T ) { StackType S; BitreeNode * p; S.makeEmpty( ); p = T; // 初始化 do{ while ( p ) { S.Push(p); p = p→leftChild; } if ( !S.IsEmpty( ) ) { // 栈非空 p = S.getTop( ); S.Pop( ); // 退栈 printf ( p→data); // 访问根结点 p = p→rightChild; // 向右链走 } } while ( p || !S.IsEmpty( ) );}

Page 38: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

33 、利用栈的后序遍历非递归算法、利用栈的后序遍历非递归算法后序遍历时使用的栈的结点定义后序遍历时使用的栈的结点定义typedef struct StackNode { enum tag{ L, R }; BitreeNode * ptr; } StackNode;void PostOrderTraverse ( Bitree T ) {// 后序遍历根为 T 的二叉树 , 存储结构为二叉链表 ,//S 是存储所经过二叉树结点的工作栈。其中 , tag// 是结点标记。当 tag = L 时 , 表示刚才是在左子树 // 中 , 从左子树退出时 , 还要去遍历右子树。当 tag// = R 时 , 表示刚才是在右子树中 , 在从右子树中退 // 出时 , 去访问位于栈顶的结点。

ptr tag (LR)

Page 39: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

StackType S; BitreeNode * p; StackNode w; S.makeEmpty( ); p = T; // 初始化 do { while ( p ) { w.ptr = p; w.tag = L; S.Push(w); p = p→leftChild; } // 遍历左子树并把经过结点加左标记进栈 int continue = 1; // 继续循环标记 while ( continue && !S.IsEmpty( ) ) { w = S.getTop( ); S.Pop( ); p = w.ptr; switch (w.tag) { //判断栈顶的 tag 标记 case L : w.tag = R; S.Push(w); continue = 0; //修改栈顶 tag p = p→rightChild; break;

Page 40: 树和森林的概念 二叉树  (Binary Tree) 二叉树的表示 二叉树遍历  (Binary Tree Traversal) 堆 ( Heap ) 树与森林  (Tree & Forest)

case R : printf (p→data); break; } } } while ( p || !S.IsEmpty( ) );}