📄 p236.cpp
字号:
#include <iostream.h>#include "P170.cpp"#include "Stack.h"const MaxN=30;template <class Type> class BST; //二叉搜索树的前视声明template <class Type> class BstNode : public BinTreeNode<Type> { //二叉搜索树结点类friend class BST;public: BstNode ( const Type d=0, BstNode *L=NULL, BstNode *R =NULL) //构造函数 : data (d), leftChild (L), rightChild (R) { }; ~BstNode ( ) { } friend class BST<Type>;protected: Type data; //数据域(用作关键码) BstNode<Type> *leftChild, *rightChild; //左子女和右子女链域};template <class Type> class BST : BinaryTree <Type> { //二叉搜索树类定义public: BST ( ) :root(NULL){}; //构造函数 BST ( Type value ) ; BST (const BST<Type> & T) ;//构造函数 ~BST ( ) { MakeEmpty ( ); } //析构函数 const BST & operator = ( const BST & Value ); void MakeEmpty( ) { destroy (root); root=NULL; } void PrintTree ( ) const { PrintTree ( root ); } int Find ( const Type & x ) const { return (Find ( x, root )!=NULL) ; } //搜索元素 Type Min() { return Min(root)->data;}; //求最小 Type Max() { return Max(root)->data;}; //求最大 int Insert ( const Type & x ) { return Insert ( x, root ); } //插入新元素 int Remove (const Type & x ) { return Remove ( x, root ); } //删除含x的结点 BstNode<Type> *Split ( Type i, BST<Type> &B, Type &x, BST<Type> &C ); void OpticBST ( int p[ ], int q[ ], Type a[ ], int n ); friend class BSTIterator ;//中序游标类 private: //在关键码i处分解二叉搜索树 BstNode<Type> *root; //二叉搜索树的根指针 Type RefValue; //数据输入停止的标志, 用于输入 BstNode<Type> *lastfound; //最近搜索到的结点的指针// void MakeEmpty ( BstNode<Type> * ptr ); //置空 int Insert ( const Type & x, BstNode<Type> * & ptr ); //插入 int Remove ( const Type & x, BstNode<Type> * & ptr ); //删除 void PrintTree ( BstNode<Type> * ptr ) const; //打印 BstNode<Type> *Copy (const BstNode<Type> * ptr ); //复制 BstNode<Type> *Find (const Type & x, BstNode<Type> * ptr ) const; //搜索 BstNode<Type> *Min ( BstNode<Type> * ptr ) const; //求最小 BstNode<Type> *Max ( BstNode<Type> * ptr ) const; //求最大 };/*template <class Type> BstNode<Type> * BST<Type>::Find (const Type & x, BstNode<Type> * ptr ) const {//私有函数:在以ptr为根的二叉搜索树中搜索含x的结点。若找到,则函数返回该结点的地址,否则函数返回//NULL值。 if ( ptr == NULL ) return NULL; else if ( x < ptr->data ) return Find ( x, ptr->leftChild ); //到左子树中继续搜索 else if ( x > ptr->data ) return Find( x, ptr->rightChild ); //到右子树中继续搜索 else return ptr; //搜索成功}*/template <class Type> BstNode<Type> *BST<Type>::Find (const Type & x, BstNode<Type> * ptr ) const {//私有函数: 说明与程序7.14相同 if ( ptr != NULL ) { //树空返回 BstNode<Type> * temp = ptr; //从根开始搜索 while ( temp != NULL ) { //==NULL表示搜索失败 if ( temp->data == x ) return temp; //搜索成功 if ( temp->data < x ) temp = temp->rightChild; //否则,继续搜索右子树 else temp = temp->leftChild; //否则,继续搜索左子树 } } return NULL;};template <class Type> int BST<Type>::Insert (const Type & x, BstNode<Type> * & ptr) {//私有函数:在以ptr为根的二叉搜索树中插入所含值为x的结点。若在树中已经有含x的结点,则不插入。 if ( ptr == NULL ) { //新结点作为叶结点插入 ptr = new BstNode<Type> (x); //创建新结点 if ( ptr == NULL ) return 0; else return 1; } else if ( x < ptr->data ) return Insert ( x, ptr->leftChild ); //小于根的关键码, 向左子树插入 else if ( x > ptr->data ) return Insert ( x, ptr->rightChild ); //大于, 向右子树插入 return 1; //除上述情况外, 就是x已在树中的情形, 不再插入}template <class Type>BST<Type>::BST ( Type value ) {//输入一个元素序列, 建立一棵二叉搜索树 Type x; root = NULL; RefValue = value; //置空树 cin >> x; //输入数据 while ( x != RefValue ) { //RefValue是一个输入结束标志 Insert ( x, root ); cin >> x; //插入,再输入数据 }}template <class Type>void BST<Type>::PrintTree ( BstNode<Type> * ptr ) const //打印{ if (ptr!=NULL) { cout<<ptr->data; cout<<"("; PrintTree(ptr->leftChild); cout<<","; PrintTree(ptr->rightChild); cout<<")"; }}template <class Type> int BST<Type>::Remove (const Type &x, BstNode<Type> * &ptr) {//私有函数:在以ptr为根的二叉搜索树中删除含x的结点。若删除成功则新根通过ptr返回。 BstNode<Type> * temp; if ( ptr != NULL ) if ( x < ptr->data ) return Remove ( x, ptr->leftChild ); //在左子树中执行删除 else if ( x > ptr->data ) return Remove ( x, ptr->rightChild ); //在右子树中执行删除 else if ( ptr->leftChild != NULL && ptr->rightChild != NULL ) { // ptr指示关键码为x的结点,它有两个子女 temp = Min ( ptr->rightChild ); //在ptr的右子树中搜寻最小结点 ptr->data = temp->data; //用该结点数据代替根结点数据 return Remove ( ptr->data, ptr->rightChild ); //在右子树中删除该结点 } else { // ptr指示关键码为x的结点,它只有一个或零个子女 temp = ptr; if ( ptr->leftChild == NULL ) ptr = ptr->rightChild; //只有右子女 else if ( ptr->rightChild == NULL ) ptr = ptr->leftChild; //只有左子女 delete temp; return 1; } else return 0;}template <class Type> class InorderIterator { //中序游标类定义public: InorderIterator ( BST<Type> & Tree ) : ref (Tree) { Init ( ); } int Init ( ); //初始化 int operator ! ( ); //求反 Type operator ( ) ( ); //取栈顶元素值 int operator ++ ( ); // BST按前序进行遍历private: BST<Type> & ref; //二叉搜索树对象 Stack < BstNode<Type> * > itrStack; //迭代工作栈};template <class Type> int InorderIterator<Type>::Init ( ) { //初始化操作 itrStack.MakeEmpty ( ); //置迭代工作栈为空 if ( ref.root != NULL ) itrStack.Push ( ref.root ); //若二叉搜索树不空则根指针进栈 return ! itrStack.IsEmpty ( ); //若栈空则返回0,否则返回1}template <class Type> int InorderIterator<Type>::operator ! ( ) { return ! itrStack.IsEmpty ( ); //若栈空则返回0,否则返回1}template <class Type> Type InorderIterator<Type>::operator ( ) ( ) { //返回当前结点的数据值 Node<Type> * current = itrStack.GetTop ( ); //取栈顶结点为当前结点 return current->data; //返回当前结点的关键码}template <class Type> int InorderIterator<Type>::operator ++ ( ) {//按二叉搜索树结点的前序序列进栈。还可以向前走则函数返回1, 否则返回0。 BstNode<Type> * current = itrStack.GetTop ( ); //取存在栈顶上的结点 BstNode<Type> * next = current->leftChild; //左子女 if ( next != NULL ) { itrStack.Push ( next ); return 1; } //左子女非空, 进栈(向左子树遍历) while ( ! itrStack.IsEmpty ( ) ) { //否则, 若栈非空 current = itrStack.Pop ( ); next = current->rightChild; //退栈, 取其右子女 if ( next != NULL ) { itrStack.Push ( next ); return 1; } //右子女非空, 进栈 } return 0;}/*template <class Type>BST<Type>::BST (const BST<Type> & T) : root (NULL) {//构造函数:根据参数初始化树T InorderIterator<Type> itr ( Type ); //声明中序游标类对象 for ( itr.init ( ); ! itr; itr++) Insert ( itr ( ) ); //按前序顺序插入}*/template <class Type>BstNode<Type> * BST<Type>::Min ( BstNode<Type> * ptr ) const //求最小{ BstNode<Type> * temp1,*temp2; temp1=ptr; if (ptr!=NULL) { if (ptr->leftChild!=NULL) { temp2=Min(ptr->leftChild); if (temp1->data>temp2->data) temp1=temp2; } if (ptr->rightChild!=NULL) { temp2=Min(ptr->rightChild); if (temp1->data>temp2->data) temp1=temp2; } } return temp1;}template <class Type>BstNode<Type> * BST<Type>::Max ( BstNode<Type> * ptr ) const //求最小{ BstNode<Type> * temp1,*temp2; temp1=ptr; if (ptr!=NULL) { if (ptr->leftChild!=NULL) { temp2=Max(ptr->leftChild); if (temp1->data<temp2->data) temp1=temp2; } if (ptr->rightChild!=NULL) { temp2=Max(ptr->rightChild); if (temp1->data<temp2->data) temp1=temp2; } } return temp1;}template <class Type> void BST<Type>::OpticBST ( int p[ ], int q[ ], Type a[ ], int n ) {//给定n个不同的数据 a[1] < a[2] < … < a[n], 以及它们具有的权值p[j], 1 ( j ( n, 另外落在它们之间外部//结点上的权值分别为 q[i], 0 ( i ( n。本算法计算a[i+1], ……, a[j]的最优二叉搜索树T[i][j]的代价C[i][j],//T[i][j]的根R[i][j]和权W[i][j]。 int R[MaxN+1][MaxN+1]; int C[MaxN+1][MaxN+1]; int W[MaxN+1][MaxN+1]; for ( int i=0; i<n; i++) { W[i][i] = q[i]; C[i][i] = R[i][i] = 0; //初始化 W[i][i+1] = W[i][i] + p[i+1] + q[i+1]; //构造只有一个内部结点, 两个外部结点的最优二叉搜索树 R[i][i+1] = i+1; //这些树的根在i+1 C[i][i+1] = W[i][i+1]; //这些树的总带权路径长度(代价) } W[n][n] = q[n]; R[n][n] = C[n][n] = 0; for ( int m=2; m<=n; m++ ) //构造具有m个内部结点的最优二叉搜索树 for ( i=0; i<=n-m; i++ ) { int j = i + m; W[i][j] = W[i][j-1] + p[j] + q[j]; //在前一棵树基础上再加一内部结点和一外部结点 int min = C[i+1][j], u = i+1; //假定i+1为根, 计算代价 for ( int k=i+2; k<=j; k++ ) if ( C[i][k-1] + C[k][j] < min ) { min = C[i][k-1] + C[k][j]; u = k; } //轮流以i+2,…,j为根, 选代价最小的送min, 其根为u C[i][j] = W[i][j] + min; R[i][j] = u; } Stack < int > nodeStack; MakeEmpty(); nodeStack.Push(0); nodeStack.Push(n); while (!nodeStack.IsEmpty()) { int j=nodeStack.Pop(); int i=nodeStack.Pop(); Insert(a[R[i][j]]); if ((i+1)<R[i][j]) { nodeStack.Push(i); nodeStack.Push(R[i][j]-1); }; if ((R[i][j])<j) { nodeStack.Push(R[i][j]); nodeStack.Push(j); }; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -