ADT template class Type class Binary Tree Binary
二叉树的ADT template <class Type> class Binary. Tree; // 二叉树类 Binary. Tree 的向前说明 template <class Type> class Binary. Node { friend class Binary. Tree < Type>; public: Binary. Node ( ) : left(NULL), right(NULL) { } // 二叉树结点的构造函数。 Binary. Node ( Type item, Binary. Node < Type> * L = NULL, Binary. Node < Type> * R = NULL ): data(item), left(L), right( R) { } ~Binary. Node ( ) { } Type Get. Data ( ) const { return data; } // 得到二叉树结点的数据值。 Binary. Node<Type> * Get. Left( ) const { return left; } //得到二叉树结点的左儿子地址。 inary. Node<Type> * Get. Right( ) const { return right; } //得到二叉树结点的左儿子地址。 void Set. Data ( const Type & item ) { data = item; } // 设置二叉树结点的数据值。 void Set. Left (Binary. Node < Type> * L ) { left = L; } // 设置二叉树结点的左儿子地址。 void Set. Right (Binary. Node < Type> * R ) { right = R; } // 设置二叉树结点的右儿子地址。
二叉树的ADT template <class Type> class Binary. Tree; // 二叉树类 Binary. Tree 的向前说明 template <class Type> class Binary. Node { friend class Binary. Tree < Type>; public: void Print. Pre. Order( ) const; // 按前序打印二叉树的结点的数据值。 void Print. Post. Order( ) const; // 按后序打印二叉树的结点的数据值。 void Print. In. Order( ) const; // 按中序打印二叉树的结点的数据值。 Binary. Node<Type> * Duplicate( ) const; // 复制以本结点为根的子树。 private: Binary. Node < Type> * left , * right ; // 结点的左、右儿子的地址 Type data; // 结点的数据信息 };
二叉树的ADT template <class Type> class Binary. Tree { public: Binary. Tree( ) : root( NULL) { } // 构造空二叉树 Binary. Tree ( const Type & value ) { root = new Binary. Node<Type> ( value ); } ~Binary. Tree ( ) { Del. Tree ( root ); } int Is. Empty ( ) const { return root == NULL; } // 二叉树为空,返回非 0,否则为 0。 const Binary. Node<Type> * Getroot( )const { return root; } int Make. Empty ( ) { Del. Tree( root); root == NULL; } // 使二叉树为空。 const Binary. Tree<Type> & operator = ( const Binary. Tree<Type> & T); private: Binary. Node<Type> * root; // 二叉树的根结点。 Binary. Tree( const Binary. Tree<Type> & ); void Del. Tree( Binary. Node<Type> * T ); }; template <class Type> const Binary. Tree<Type> & Binary. Tree<Type> : : operator = ( const Binary. Tree<Type> & T ) { if ( this != &T ) { Del. Tree(root); // 其具体实现,见程序 5. 1。 if ( T. root != NULL ) root = T. root->Duplicate( ); } }
二叉树的ADT ·二叉树的 ADT:求二叉树的结点个数和高度以及删除一棵二叉树。 template <class Type> Type Max( const Type u, const Type v ) { if ( u > v ) return u; else return v; } template <class Type> int Binary. Node < Type> : : Size ( const Binary. Node <Type> * T ) const { // 得到以 T 为根的二叉树或子树的结点个数。 if ( T == NULL ) return 0; else return 1 + Size( T->left ) + Size( T->right); } template <class Type> int Binary. Node < Type> : : Height ( const Binary. Node < Type> * T ) const { // 得到以 T 为根的二叉树的高度。 if ( T == NULL ) return 0; else return 1 + Max( Height( T->left ), Height( T->right)); }
二叉树的ADT ·二叉树的 ADT:求二叉树的结点个数和高度以及删除一棵二叉树。 template <class Type> void Binary. Tree<Type> : : Del. Tree ( Binary. Node < Type> // 删除以 T 为根的二叉树的所有结点。 if ( T != NULL ) { Del. Tree( T->left); Del. Tree( T->right); delete T; } } * T ) {
二叉树遍历的迭代器类 • 二叉树的迭代器:Tree Iterator ADT 5. 3: 二叉树的迭代器类。 template <class Type> class Tree. Iterator { public: Tree. Iterator ( const Binary. Tree < Type > & BT ) : T( BT ), current( NULL) { } virtual ~Tree. Iterator ( ) { } virtual void First ( ) = 0; // 第一个被访问的结点地址送current virtual void operator ++ ( ) = 0; // 下一个被访问的结点地址送current int operator + ( )const{ return current != NULL; }//当前结点为空吗,非空返回 True const Type & operator ( ) const; // 返回当前结点指针 current 所指向的结点的数据值。 protected: const Binary. Tree <Type > & T; const Binary. Node<Type > * current; // 指向当前结点的指针。 private: Tree. Iterator ( const Tree. Iterator & ) { } const Tree. Iterator & operator = ( const Tree. Iterator & ); }; template <class Type> const Type & Tree. Iterator <Type> : : operator ( ) const Exception( current == NULL, “This node is NULL!” ); return current->Get. Data( ); } {
前序遍历的迭代器 • 遍历二叉树:Tree Iterator :前序的实现。 template <class Type> class Preorder : public Tree. Iterator < Type > { public: Preorder( const Binary. Tree < Type > & R ); ~Preorder( ) { } void First( ); void operator ++ ( ); void Preorder_NLR ( ); protected: Stack < const Binary. Node <Type > * > s; }; template <class Type> Preorder<Type> : : Preorder( const Binary. Tree <Type> & R ) : Tree. Iterator<Type > ( R ) { s. Push( T. Getroot( ) ); } template <class Type> void Preorder <Type> : : First ( ) { s. Make. Empty ( ); if ( T. Getroot( ) ) s. Push( T. Getroot( ) ); operator ++( ); } //堆栈清空。若二叉树T非空,则根结点进栈,并得到当前结点。
前序遍历的迭代器 • 遍历二叉树:Tree Iterator :前序的实现。 template <class Type> void Preorder <Type> : : operator ++ ( ) { if ( s. Is. Empty() ) { if ( current == NULL ) { cerr << “Advanced past end ” << endl; exit( 1 ) }; current = NULL; return; } current = s. Top( ); s. Pop( ); // 得到当前结点的地址,并进行出栈操作。 if ( current ->Get. Right ( ) != NULL ) s. Push( current->Get. Right( ) ); //非空右儿子进栈。 if ( current ->Get. Left ( ) != NULL ) s. Push( current->Get. Left( ) ); //非空左儿子进栈。 } template <class Type> void Preorder < Type > : : Preorder_NLR ( ) { First( ); // 将当前指针 current 指向根结点。 while( operator +( ) ){ // 当前指针 current 非空时继续执行。 cout << operator()() << endl; // 输出当前结点的数据场之值。 operator ++( ); // 使前序次序下的下一个结点成为当前结点。 } }
后序遍历的迭代器 • 遍历二叉树:Tree Iterator 后序的实现 template <class Type> struct St. Node { const Binary. Node<Type > * Node; int Times. Pop; St. Node( const Binary. Node <Type > * N = NULL ): Node(N), Times. Pop(0) { } }; template <class Type> class Postorder : public Tree. Iterator < Type > { public: Postorder( const Binary. Tree < Type > & R ); ~Postorder( ) { } void First( ); // 后序遍历时的第一个结点的地址。 void operator ++ ( ); // 后序遍历时的下一个结点的地址。 protected: Stack < St. Node<Type> > s; }; template <class Type> Postorder<Type> : : Postorder(const Binary. Tree<Type> & R) : Tree. Iterator<Type> (R) { s. Push( St. Node<Type>( T. Getroot( ) ) ); } template <class Type> void Postorder <Type> : : First ( ) { // 得到第一个访问的结点地址 s. Make. Empty ( ); if ( T. Getroot( ) ) s. push ( St. Node<Type>( T. Getroot( ) ); operator ++ ( ); } // 根结点地址及标志 0 进栈,去寻找第一个被访问的最左方的叶子。
后序遍历的迭代器 • 遍历二叉树:Tree Iterator 后序的实现 template <class Type> void Postorder <Type>: : operator ++ ( ) { if ( s. Is. Empty() ) { // 当栈空且 current 也为空时,遍历结束。 if ( current == NULL ) { cerr << “Advanced past end ” << endl; exit( 1 ); } current = NULL; return; } // 置当前指针为空,结束。 St. Node<Type> Cnode; for ( ; ; ) { Cnode = s. Top( ); s. Pop( ); if ( ++ Cnode. Time. Pop == 3 ) { current = Cnode. Node; return; } //其左右子树处理完毕, 该结点可访问。 s. Push( Cnode ); if ( Cnode. Times. Pop == 1 ) // 转向访问左子树。 { if ( Cnode. Node -> Get. Left ( ) != NULL ) // 有左儿子,进栈。 s. Push(St. Node<Type>( Cnode. Node -> Get. Left ( ) ) ); } else { } } } // Cnode. Time. Pop == 2 访左结束,转向访问右子树。 if ( Cnode. Node -> Get. Right ( ) != NULL ) s. Push(St. Node<Type>( Cnode. Node -> Get. Right ( ) ) );
中序遍历的迭代器 程序 5. 5: 中序遍历迭代器类 template <class Type> class Inorder : public Postorder < Type > { public: Inorder( const Binary. Tree < Type > & R ) : Postorder<Type> (R) { } void operator ++ ( ); // 中序时的下一个结点的地址。 }; template <class Type> void Inorder<Type>: : operator ++ ( ) { if ( s. Is. Empty() ) { // 当栈空且 current 也为空时,遍历结束。 if ( current == NULL ) {cerr<< “Advanced past end ”<<endl; exit(1); } Cnode = NULL; return; } // 置当前指针为空,结束。 St. Node<Type> Cnode; for ( ; ; ) { current = s. Top( ); s. Pop( ); if ( ++Cnode. Times. Pop == 2 ) // 其左子树处理完毕, 该结点可访问。 { current = Cnode. Node; if ( Cnode. Node -> Get. Right ( ) != NULL ) // 有右儿子,进栈。 s. Push(St. Node<Type>( Cnode. Node->Get. Right() ) ); return; } s. Push( Cnode); if ( Cnode. Node -> Get. Left ( ) != NULL ) s. Push(St. Node<Type>( Cnode. Node->Get. Left() ) ); } }
中序穿线树的中序遍历 · 中序穿线树遍历的实现算法。 template <class Type> int Inorder. Thread. Tree<Type> : : First ( ) { current = root; if ( !current ) return current; //为 0是中序穿线二叉树空的标志。 while( arr[current]. left >0 ) current = arr[current]. left; return current; // 在中序次序下第一个被访问的结点的下标地址。 A } root template <class Type> L C int Inorder. Thread. Tree<Type> : : Next ( ) { aftcurrent = arr[current]. right; if ( aftcurrent <= 0 ) { current = - aftcurrent; return current; } D B E // 为 0是中序遍历结束的标志,否则是中序次序下的下一个结点的地址。 无后继结点 while( arr[aftcurrent]. left > 0 ) aftcurrent = arr[aftcurrent]. left; current = aftcurrent; return current; //在中序次序下的下一个被访问的结点的地址。 } template <class Type> void Inorder. Thread. Tree<Type> : : Inorder ( ){ int p = First( ); while( p != 0 ) { cout << arr[p]. data << endl; p = Next( ); } return; }
中序穿线树 template <class Type> Istream & operator >> (istream & in, Inorder. Thread. Tree<Type> & x){ int size, j, k = 2; Type ele; cout << “Enter size of your Inorder. Thread. Tree array! ” << endl; in >> size; if (size > x. Max. Size ) { cout << “Error: out of spaces!”; return in; } cout << “ Enter data of every element one by one!” << endl; in >> ele; if (ele == x. flag) { cout << “Input data end!” << endl; return in; } x. arr[1]. setdata (ele); x. root = 1; // 根结点单独生成。 while ( in >> ele, ele != x. flag) { j = x. root; x. arr[k]. setdata (ele); while(1 ) { if ( x. arr[k]. data < x. arr[j]. data ) if ( x. arr[j]. left > 0) j = x. arr[j]. left; else { x. arr[k]. left = x. arr[j]. left; x. arr[k]. right = -j; x. arr[j]. left = k; break; } // 新结点 k 插入后为结点 j 的左儿子,是叶子。 else if ( x. arr[j]. right > 0) j = x. arr[j]. right; else { x. arr[k]. right = x. arr[j]. right; x. arr[k]. left = -j; x. arr[j]. right = k; break; } // 新结点 k 插入后为结点 j 的右儿子,是叶子。 } k++; } return in; }
最小化堆的最小元素 root 7 62 16 24 50 88 77 42
最小化堆的顺序存储 [1] 7 [2] 16 [3] root 7 1 62 16 62 2 3 [4] 24 [5] 50 24 50 88 77 [6] 88 4 5 6 7 [7] 77 43
最小化堆的ADT template < class EType> Min. Heap<EType> : : Min. Heap( int sz ) { heap = new EType[sz + 1]; Current. Size = 0; Max. Size = sz; } // 建立存储堆的数组 heap[1]至heap[sz],此时仍是空的堆。sz 为数组的最大容量。 template<class EType> Min. Heap<EType> : : Min. Heap( EType arr[ ], int n, int sz ) { Exception( sz < n, “Max. Size is less then Current. Size!”); Current. Size = n; Max. Size = sz; heap = new EType[ sz + 1]; for ( int j = 1; j<=n; j++ ) heap[j] = arr[j]; // 对当前最小化堆进行赋值。 Build. Heap( ); } // 建立的最小化堆是heap[1]至heap[n]。sz 为数组的最大容量。 52
最小化堆的ADT 建立最小化堆的主要函数 Sift. Down 及 Build. Heap 的实现: template < class EType> void Min. Heap<EType> : : Sift. Down( int j ) { // heap[1], …, heap[n]为存储堆的数组。heap[0]不用。 int Min. Son; // 用于记录小儿子的下标地址。 heap[0] = heap[j]; // 暂时存放 heap[ j ] 至 heap[ 0 ]。 for ( ; j*2 <= Current. Size; j = Min. Son) { Min. Son = 2 * j; if ( Min. Son != Current. Size && heap [Min. Son+1 ] < heap [Min. Son ] ) Min. Son++; if ( heap[Min. Son] < heap[0] ) heap[j] = heap[Min. Son]; else break; } heap [j ] = heap[0]; // 取回 heap[ j ] 之值。 } template < class EType> void Min. Heap<EType> : : Build. Heap( ) { for ( int j = Current. Size/2; j > 0; j-- ) Sift. Down(j); 53 }
赫夫曼算法的实现:使用最小化堆挑选出最小的结点。 template <class Type> void Best. Binary. Tree ( Type weight[ ], int n, node<Type> Best. Binary. Tree[ ], int m) { // weight[1] 到weight[n]保存权值, weight[0]不用。Best. Binary. Tree[1]到 // Best. Binary. Tree[2 n-1]保存最优二叉树,Best. Binary. Tree[0 ]不用,m应为 2 n-1。 node< Type > * minptr = new node<Type>; // 暂存最小值用。 Min. Heap< node < Type > > Min. Hp(n); //建立最小化堆,容量为n个单元,0 号单元不用。 int j, k = m; for ( j = 1; j <= n; j++ ) { minptr->setdata( weight[j]); minptr->setorder(j); Min. Hp. Insert( *minptr); } for ( j = n+1; j <= m; j++ ) { Min. Hp. Delete. Min ( *minptr ); Best. Binary. Tree[k] = *minptr; Min. Hp. Delete. Min ( *minptr ); Best. Binary. Tree[k-1] = *minptr ; minptr->setdata(Best. Binary. Tree[k]. data + Best. Binary. Tree[k-1]. data, k, k -1 ); minptr->setorder(); k -= 2; Min. Hp. Insert( *minptr ); // 内部结点 bj 插入最小化堆。 } Min. Hp. Delete. Min ( *minptr ); Best. Binary. Tree[1] = *minptr; // 插入根结点。 b 3, 18 } 0 1 2 ……. n…… 2 n-2 2 n-1 b 2, 11 A, 7 T, 5 b 1, 6 C, 2 S, 4
附:自上而下建堆法简介 数组 h [1] 50 [2] 16 16 [3] 62 1 [4] 24 [5] 7 [6] 88 [7] 77 root 50 62 2 3 61
附:自上而下建堆法简介 数组 h [1] 16 [2] 50 16 [3] 62 1 [4] root 24 [5] 7 [6] 88 [7] 77 50 62 2 3 24 4 62
附:自上而下建堆法简介 数组 h [1] 16 [2] 24 16 [3] 62 1 [4] root 50 [5] 7 [6] 88 [7] 77 24 62 2 3 50 4 63
附:自上而下建堆法简介 数组 h [1] 16 [2] 24 16 [3] 62 1 [4] root 50 [5] 7 [6] 88 [7] 77 24 62 2 3 50 7 4 5 64
附:自上而下建堆法简介 数组 h [1] 16 [2] 7 16 [3] 62 1 [4] root 50 [5] 24 [6] 88 [7] 77 7 62 2 3 50 24 4 5 65
附:自上而下建堆法简介 数组 h [1] 7 [2] 16 7 [3] 62 1 [4] root 50 [5] 24 [6] 88 [7] 77 16 62 2 3 50 24 4 5 66
附:自上而下建堆法简介 数组 h [1] 7 [2] 16 7 [3] 62 1 [4] root 50 [5] 24 [6] 88 [7] 77 16 62 2 3 50 24 88 4 5 6 67
附:自上而下建堆法简介 数组 h [1] 7 [2] 16 7 [3] 62 1 [4] root 50 [5] 24 [6] 88 [7] 77 16 62 2 3 50 24 88 77 4 5 6 7 68
- Slides: 86