实验二 伸展树算法设计与实现
一、实验名称:伸展树算法设计与实现
二、实验目的:
1.掌握伸展树的数据结构。
2.掌握伸展算法的实现。
三、实验内容
完善下列程序,并回答问题。
1 #include <iostream.h> 2 enum ResultCode{Underflow, Overflow, Success, Duplicate, Fail, NotPresent}; 3 template<class T> 4 struct BTNode 5 {//二叉树结点类 6 BTNode(const T& x){ element=x; lChild=rChild=NULL; } 7 T element; 8 BTNode* lChild,*rChild; 9 }; 10 template<class T> 11 class SPTree 12 {//伸展树类 13 public: 14 SPTree(){root=NULL;} 15 ResultCode Insert(T x); 16 void printTree(){cout<<"该树的边分别为:"<<endl; printTree(root);}; 17 void printTree( BTNode<T>* &p){ 18 if(p == NULL) return; 19 if(p->lChild != NULL){ 20 cout<<" 从"<<p->element<<"到"<<p->lChild->element<<endl; 21 printTree(p->lChild); 22 } 23 if(p->rChild != NULL){ 24 cout<<" 从"<<p->element<<"到"<<p->rChild->element<<endl; 25 printTree(p->rChild); 26 } 27 }; 28 void printTree(int level){cout<<"该树为:"; printTree(root, level); cout<<endl;}; 29 void printTree( BTNode<T>* &p, int level){ 30 if(p == NULL) return; 31 if(p->lChild != NULL){ 32 printTree(p->lChild, level+1); 33 } 34 cout<<endl; 35 for(int i = 0; i<level; i++) cout<<" "; 36 cout<<p->element; 37 if(p->rChild != NULL){ 38 printTree(p->rChild, level+1); 39 } 40 }; 41 protected: 42 BTNode<T>* root; 43 private: 44 ResultCode Insert(BTNode<T>* &p, T x); 45 void LRot(BTNode<T>* &p); 46 void RRot(BTNode<T>* &p); 47 }; 48 49 template <class T> 50 void SPTree<T>::LRot(BTNode<T>*& p) 51 { //实现向左旋转 52 学生自己书写部分 53 } 54 template <class T> 55 void SPTree<T>::RRot(BTNode<T>*& p) 56 { //实现向右旋转 57 学生自己书写部分 58 } 59 60 template <class T> 61 ResultCode SPTree<T>::Insert(T x) 62 { 63 return Insert(root, x); 64 } 65 template <class T> 66 ResultCode SPTree<T>::Insert(BTNode<T>* &p, T x) 67 { 68 学生自己书写部分 69 } 70 71 void main(){ 72 SPTree<int> tree; 73 int ele[30] = {75,89,72,42,18,25,99,90,17,33}; 74 int n = 10; 75 for(int i = 0; i < n; i++) tree.Insert(ele[i]); 76 cout<<"---伸展树程序---"<<endl<<endl; 77 cout<<"依次插入的数为:"; 78 for(int j = 0; j < n; j++) cout<<ele[j]<<","; 79 tree.printTree(); 80 tree.printTree(0); 81 }
补充后的程序:
1 #include <iostream.h> 2 enum ResultCode{Underflow, Overflow, Success, Duplicate, Fail, NotPresent}; 3 template<class T> 4 struct BTNode 5 {//二叉树结点类 6 BTNode(const T& x){ element=x; lChild=rChild=NULL; } 7 T element; 8 BTNode* lChild,*rChild; 9 }; 10 template<class T> 11 class SPTree 12 {//伸展树类 13 public: 14 SPTree(){root=NULL;} 15 ResultCode Insert(T x); 16 void printTree(){cout<<"该树的边分别为:"<<endl; printTree(root);}; 17 void printTree( BTNode<T>* &p){ 18 if(p == NULL) return; 19 if(p->lChild != NULL){ 20 cout<<" 从"<<p->element<<"到"<<p->lChild->element<<endl; 21 printTree(p->lChild); 22 } 23 if(p->rChild != NULL){ 24 cout<<" 从"<<p->element<<"到"<<p->rChild->element<<endl; 25 printTree(p->rChild); 26 } 27 }; 28 void printTree(int level){cout<<"该树为:"; printTree(root, level); cout<<endl;}; 29 void printTree( BTNode<T>* &p, int level){ 30 if(p == NULL) return; 31 if(p->lChild != NULL){ 32 printTree(p->lChild, level+1); 33 } 34 cout<<endl; 35 for(int i = 0; i<level; i++) cout<<" "; 36 cout<<p->element; 37 if(p->rChild != NULL){ 38 printTree(p->rChild, level+1); 39 } 40 }; 41 protected: 42 BTNode<T>* root; 43 private: 44 ResultCode Insert(BTNode<T>* &p, T x); 45 void LRot(BTNode<T>* &p); 46 void RRot(BTNode<T>* &p); 47 }; 48 49 template <class T> 50 void SPTree<T>::LRot(BTNode<T>*& p) 51 { //实现向左旋转 学生自己书写部分 52 BTNode<T>* r=p->rChild; 53 p->rChild=r->lChild; 54 r->lChild=p;p=r; 55 56 } 57 template <class T> 58 void SPTree<T>::RRot(BTNode<T>*& p) 59 { //实现向右旋转学生自己书写部分 60 BTNode<T>* r=p->lChild; 61 p->lChild=r->rChild; 62 r->rChild=p;p=r; 63 64 } 65 66 template <class T> 67 ResultCode SPTree<T>::Insert(T x) 68 { 69 return Insert(root, x); 70 } 71 template <class T> 72 ResultCode SPTree<T>::Insert(BTNode<T>* &p, T x) 73 { 74 //学生自己书写部分 75 ResultCode result=Success; 76 BTNode<T>* r; 77 if(p==NULL){ 78 p=new BTNode<T>(x);return result; 79 } 80 if(x==p->element) 81 { 82 result=Duplicate;return result; 83 } 84 if(x<p->element) 85 { 86 r=p->lChild; 87 if(r==NULL){ 88 r=new BTNode<T>(x);r->rChild=p;p=r; 89 return result; 90 } 91 else if(x==r->element){ 92 RRot(p);result=Duplicate;return result; 93 } 94 if(x<r->element){ 95 result=Insert(r->lChild,x); 96 RRot(p); 97 } 98 else{ 99 result=Insert(r->rChild,x); 100 LRot(r);p->lChild=r; 101 } 102 RRot(p); 103 } 104 else{ 105 r=p->rChild; 106 if(r==NULL){ 107 r=new BTNode<T>(x);r->lChild=p;p=r; 108 return result; 109 } 110 else if(x==r->element) 111 { 112 LRot(p); 113 result=Duplicate;return result; 114 } 115 if(x>r->element){ 116 result=Insert(r->rChild,x);LRot(p); 117 } 118 else{ 119 result=Insert(r->lChild,x); 120 RRot(r);p->rChild=r; 121 } 122 LRot(p); 123 } 124 return result; 125 } 126 127 int main(){ 128 SPTree<int> tree; 129 //int ele[30] = {75,89,72,42,18,25,99,90,17,33}; 130 int ele[30] = {25,99,90,17,75,89,72,42,18}; 131 int n = 10; 132 for(int i = 0; i < n; i++) tree.Insert(ele[i]); 133 cout<<"---伸展树程序---"<<endl<<endl; 134 cout<<"依次插入的数为:"; 135 for(int j = 0; j < n; j++) cout<<ele[j]<<","; 136 tree.printTree(); 137 tree.printTree(0); 138 }
程序问题:
- 请回答:Insert函数的两个参数分别表示的语义是什么。
- 画出伸展树插入算法的基本流程图,或者用自然语言描述整个插入算法的实现过程。
- 若以此输入数字:75、89、72、42、18、25、99、90、17、33。最终的图像是什么,请画出节点示例图。
- 若输入的数字为:25、99、90、17、75、89、72、42、18。最终的图像是什么。
- (选作)在源程序的基础上,编写访问函数access(T x),实现x在树中,则返回指向它的指针,否则返回空指针。无论成功与否,都将进行伸展操作,成功则该节点为树根节点,不成功则最后一个查找的节点为根节点。并回答问题。
实现思想:改写Insert函数。
问题1. 针对4个问题,依次访问18、42、72、90、42、75、90、72、42、18、72以后,该树的图像是什么。
四、实验小结和心得