数据结构-2. 二叉树
2. 二叉树
2.1 定义及主要特征
2.1.1 定义
1) 二叉树由节点的有限集合组成
2) 树的高度等于最深节点的深度加1。
3) 分支节点(内节点):至少有一个非空子树的节点。
4) 满二叉树(full binary tree):每个节点要么是有两个非空子节点的分支节点,要么是叶节点。
5) 完全二叉树:从根节点起,每一层从左到右填充。
2.1.2 满二叉树定理
1) 非空满二叉树的叶结点数等于其分支结点数加 1。
2) 一棵非空二叉树空子树的数目等于其结点数目加 1。
2.2 二叉树的周游
1) 前序周游(preorder traversal):先访问节点,后访问其子节点。
2) 中序周游(inorder traversal):先访问左子节点,然后访问该节点,最后访问右子节点。
3) 后序周游(postorder traversal):先访问节点的子节点,然后再访问该节点。
2.3 二叉树的实现
2.3.1 使用指针实现二叉树
1 template<class Elem> 2 class BinNode{ 3 public: 4 virtual Elem& val()=0; 5 virtual void setVal(const Elem&)=0; 6 virtual BinNode* left() const=0; 7 virtual void setLeft(BinNode*)=0; 8 virtual BinNode* right() const=0; 9 virtual void setRight(BinNode*)=0; 10 virtual bool isLeaf()=0; 11 }; 12 13 template<class Elem> 14 class BinNodePtr:public BinNode<Elem>{ 15 private: 16 Elem it; 17 BinNodePtr* lc; 18 BinNodePtr* rc; 19 public: 20 BinNodePtr(){ 21 lc=rc=NULL; 22 } 23 BinNodePtr(Elem e,BinNodePtr* l=NULL,BinNodePtr* r=NULL){ 24 it=e; 25 lc=l; 26 rc=r; 27 } 28 ~BinNodePtr(){} 29 Elem& val(){return it;} 30 void setVal(const Elem& e){it=e;} 31 inline BinNodePtr<Elem>* left()const{return lc;} 32 void setLeft(BinNode<Elem>*b){lc=(BinNodePtr*)b;} 33 inline BinNodePtr<Elem>* right()const{return rc;} 34 void setRight(BinNode<Elem>*b){rc=(BinNodePtr*)b;} 35 bool isLeaf(){return (lc==NULL)&&(rc=NULL);} 36 void traverse(BinNodePtr* subroot){ 37 if(subroot==NULL) 38 return; 39 if(subroot->isLeaf()) 40 cout<<"Leaf:"<<subroot->val()<<"\n"; 41 else{ 42 traverse(subroot->left()); 43 cout<<"Internal:"<<subroot->val()<<"\n"; 44 traverse(subroot->right()); 45 } 46 } 47 };
2.3.2 使用数组实现完全二叉树
位置 0 1 2 3 4 5 6
父节点
左子节点
右子节点
左兄弟节点
右兄弟节点
Parent(r) = (r-1)/2 , 当r≠0时
Leftchild(r) = 2r+1 , 当2r+1<n时
Rightchile(r) = 2r+2 , 当2r+2<n时
Leftsibling(r) = r-1 ,当r为偶数并且0≤r≤n-1时
Rightsibling(r) = r+1 , 当r为奇数并且r+1<1时。
2.4 二叉查找树
2.4.1 定义
二叉查找树是满足下面条件的二叉树:对于二叉查找树的一个节点,设其值为 K,则该节点左子树中任意一个节点的值都小于 K,该节点右子树中任意一个节点的值都大于或等于 K。
2.4.2 BST实现
1 template<class Elem> 2 class BinNode{ 3 public: 4 virtual Elem& val()=0; 5 virtual void setVal(const Elem&)=0; 6 virtual BinNode* left() const=0; 7 virtual void setLeft(BinNode*)=0; 8 virtual BinNode* right() const=0; 9 virtual void setRight(BinNode*)=0; 10 virtual bool isLeaf()=0; 11 }; 12 13 template<class Elem> 14 class BinNodePtr:public BinNode<Elem>{ 15 private: 16 Elem it; 17 BinNodePtr* lc; 18 BinNodePtr* rc; 19 public: 20 BinNodePtr(){ 21 lc=rc=NULL; 22 } 23 BinNodePtr(Elem e,BinNodePtr* l=NULL,BinNodePtr* r=NULL){ 24 it=e; 25 lc=l; 26 rc=r; 27 } 28 ~BinNodePtr(){} 29 Elem& val(){return it;} 30 void setVal(const Elem& e){it=e;} 31 inline BinNodePtr<Elem>* left()const{return lc;} 32 void setLeft(BinNode<Elem>*b){lc=(BinNodePtr*)b;} 33 inline BinNodePtr<Elem>* right()const{return rc;} 34 void setRight(BinNode<Elem>*b){rc=(BinNodePtr*)b;} 35 bool isLeaf(){return (lc==NULL)&&(rc=NULL);} 36 void traverse(BinNodePtr* subroot){ 37 if(subroot==NULL) 38 return; 39 if(subroot->isLeaf()) 40 cout<<"Leaf:"<<subroot->val()<<"\n"; 41 else{ 42 traverse(subroot->left()); 43 cout<<"Internal:"<<subroot->val()<<"\n"; 44 traverse(subroot->right()); 45 } 46 } 47 }; 48 49 template<class Key,class Elem> 50 class BST{ 51 private: 52 BinNode<Elem>* root; 53 int nodecount; 54 BinNode<Elem>* inserthelp(BinNode<Elem> *subroot,const Elem &e){ 55 if(subroot==NULL){ 56 cout<<"subroot is NULL,creat new node:"<<e<<endl; 57 subroot=new BinNodePtr<Elem>(e,NULL,NULL); 58 //return subroot; 59 } 60 else if(e<subroot->val()){ 61 cout<<"current node:"<<subroot->val()<<",will insert node:"<<e<<endl; 62 if(subroot->left()==NULL){ 63 cout<<"left node is NULL,creat new left node:"<<e<<endl; 64 subroot->setLeft(new BinNodePtr<Elem>(e,NULL,NULL)); 65 //return subroot; 66 } 67 else{ 68 cout<<"left node:"<<subroot->left()->val()<<endl; 69 inserthelp(subroot->left(),e); 70 //return subroot; 71 } 72 } 73 else{ 74 cout<<"current node:"<<subroot->val()<<endl; 75 if(subroot->right()==NULL){ 76 cout<<"right node is NULL,creat new right node:"<<e<<endl; 77 subroot->setRight(new BinNodePtr<Elem>(e,NULL,NULL)); 78 //return subroot; 79 } 80 else{ 81 cout<<"right node is:"<<subroot->right()->val()<<endl; 82 inserthelp(subroot->right(),e); 83 //return subroot; 84 } 85 } 86 return subroot; 87 } 88 89 bool findhelp(BinNode<Elem>* subroot,const Key &K,Elem &e){ 90 if(subroot==NULL) 91 return false; 92 else if(K<subroot->val()) 93 return findhelp(subroot->left(),K,e); 94 else if(K>subroot->val()) 95 return findhelp(subroot->right(),K,e); 96 else{ 97 e=subroot->val(); 98 return true; 99 } 100 } 101 102 BinNode<Elem>* deletemin(BinNode<Elem>* subroot,BinNode<Elem>* &min){ 103 if(subroot->left()==NULL){ 104 min=subroot; 105 return subroot->right(); 106 } 107 else{ 108 subroot->setLeft(deletemin(subroot->left(),min)); 109 return subroot; 110 } 111 } 112 113 void clearhelp(BinNode<Elem>* subroot){ 114 if(subroot==NULL) 115 return; 116 clearhelp(subroot->left()); 117 clearhelp(subroot->right()); 118 delete subroot; 119 } 120 121 BinNode<Elem>* removehelp(BinNode<Elem>* subroot,const Key &K,BinNode<Elem>* &t){ 122 if(subroot==NULL) 123 return NULL; 124 else if(K<subroot->val()) 125 subroot->setLeft(removehelp(subroot->left(),K,t)); 126 else if(K>subroot->val()) 127 subroot->setRight(removehelp(subroot->right(),K,t)); 128 else{ 129 BinNode<Elem>* temp; 130 t=subroot; 131 if(subroot->left()==NULL) 132 subroot=subroot->right(); 133 else if(subroot->right()==NULL) 134 subroot=subroot->left(); 135 else{ 136 subroot->setRight(deletemin(subroot->right(),temp)); 137 Elem te=subroot->val(); 138 subroot->setVal(temp->val()); 139 temp->setVal(te); 140 delete temp; 141 } 142 return subroot; 143 } 144 } 145 146 void printhelp(BinNode<Elem>*subroot,int level)const{ 147 if(subroot==NULL) 148 return; 149 printhelp(subroot->left(),(level+1)); 150 for(int i=0;i<level;i++) 151 cout<<" "; 152 cout<<subroot->val()<<"\n"; 153 printhelp(subroot->right(),(level+1)); 154 } 155 156 public: 157 BST(){ 158 root=NULL; 159 nodecount=0; 160 } 161 162 ~BST(){ clearhelp(root); } 163 164 void clear(){ 165 clearhelp(root); 166 root=NULL; 167 nodecount=0; 168 } 169 170 bool insert(const Elem&e){ 171 root=inserthelp(root,e); 172 nodecount++; 173 return true; 174 } 175 176 bool remove(const Key&K,Elem&e){ 177 BinNode<Elem> t=NULL; 178 root=removehelp(root,K,t); 179 if(t==NULL) 180 return false; 181 e=t->val(); 182 nodecount--; 183 delete t; 184 return true; 185 } 186 187 bool removeAny(Elem &e){ 188 if(root==NULL) 189 return false; 190 BinNode<Elem> *t; 191 root=deletemin(root,t); 192 e=t->val(); 193 delete t; 194 nodecount--; 195 return true; 196 } 197 198 bool find(const Key &K,Elem &e)const{ 199 return findhelp(root,K,e); 200 } 201 202 int size(){ 203 return nodecount; 204 } 205 206 void print()const{ 207 if(root==NULL) 208 cout<<"The BST is empty.\n"; 209 else 210 printhelp(root,0); 211 } 212 213 };
2.5 堆
2.5.1 堆的定义
堆是一棵完全二叉树,堆中存储的数据是局部有序的。
最大值堆:任意一个节点的值都大于或等于其任意一个子节点的值。
最小值堆:任意一个节点的值都小于或等于其任意一个子节点的值。
2.5.2 最大值堆的实现
1 template<class Elem> 2 class maxheap{ 3 private: 4 Elem *heap; 5 int size; 6 int n; 7 public: 8 maxheap(Elem *h,int num,int max){ 9 heap=h; 10 n=num; 11 size=max; 12 buildHeap(); 13 } 14 int heapsize() const{ return size; } 15 16 bool isLeaf(int pos) const{ 17 return (pos>=n/2)&&(pos<n); 18 } 19 20 int leftchild(int pos) const{ 21 return 2*pos+1; 22 } 23 24 int rightchild(int pos) const{ 25 return 2*pos+2; 26 } 27 28 int parent(int pos) const{ 29 return (pos-1)/2; 30 } 31 32 bool insert(const Elem &val){ 33 if(n>=size) 34 return false; 35 int curr=n++; 36 heap[curr]=val; 37 while((curr!=0)&&(heap[curr]>heap[parent(curr)])){ 38 swap(heap,curr,parent(curr)); 39 curr=parent(curr); 40 } 41 return true; 42 } 43 44 static bool swap(Elem *Heap,int pos1,int pos2){ 45 Elem tmp=Heap[pos1]; 46 Heap[pos1]=Heap[pos2]; 47 Heap[pos2]=tmp; 48 return true; 49 } 50 51 void siftdown(int pos){ 52 while(!isLeaf(pos)){ 53 int j=leftchild(pos); 54 int rc=rightchild(pos); 55 if((rc<n)&&heap[j]<heap[rc]) 56 j=rc; 57 if(heap[pos]>=heap[j]) 58 return; 59 swap(heap,pos,j); 60 pos=j; 61 } 62 } 63 64 bool removemax(Elem &it){ 65 if(n==0) 66 return false; 67 swap(heap,0,--n); 68 if(n!=0) 69 siftdown(0); 70 it=heap[n]; 71 return true; 72 } 73 74 bool remove(int pos,Elem &it){ 75 if(pos<0||pos>=n) 76 return false; 77 swap(heap,pos,--n); 78 int curr=pos; 79 while((curr!=0)&&(heap[curr]>heap[parent(curr)])){ 80 swap(heap,curr,parent(curr)); 81 //curr=parent(curr); 82 } 83 siftdown(pos); 84 it=heap[n]; 85 86 return true; 87 } 88 89 void buildHeap(){ 90 for(int i=n/2-1;i>=0;i--) 91 siftdown(i); 92 } 93 94 void print() const{ 95 for(int i=0;i<n;i++){ 96 cout<<heap[i]<<" "; 97 } 98 cout<<endl; 99 } 100 };
2.6 Huffman编码树
1 template<class Elem> 2 class HuffNode{ 3 public: 4 virtual int weight()=0; 5 virtual bool isLeaf()=0; 6 virtual HuffNode* left()const=0; 7 virtual void setLeft(HuffNode*)=0; 8 virtual HuffNode* right()const=0; 9 virtual void setRight(HuffNode*)=0; 10 }; 11 12 template<class Elem> 13 class FrepPair{ 14 private: 15 Elem it; 16 int frep; 17 public: 18 FrepPair(const Elem &e,int f){ 19 it=e; 20 frep=f; 21 } 22 23 ~FrepPair(){} 24 25 int weight(){ return frep; } 26 27 Elem& val(){ return it; } 28 }; 29 30 template<class Elem> 31 class LeafNode:public HuffNode<Elem>{ 32 private: 33 FrepPair<Elem> *it; 34 public: 35 LeafNode(const Elem &val,int frep){ 36 it=new FrepPair<Elem>(val,frep); 37 } 38 39 int weight(){ return it->weight(); } 40 41 FrepPair*<Elem> val(){ return it; } 42 43 bool isLeaf(){ return true; } 44 45 virtual HuffNode* left() const { return NULL; } 46 47 virtual void setLeft(HuffNode*){} 48 49 virtual HuffNode* right() const { return NULL; } 50 51 virtual void setRight(HuffNode*){} 52 }; 53 54 template<class Elem> 55 class IntlNode:public HuffNode<Elem>{ 56 private: 57 HuffNode<Elem>* lc; 58 HuffNode<Elem>* rc; 59 int wgt; 60 public: 61 IntlNode(HuffNode<Elem> *l,HuffNode<Elem> *r){ 62 wgt=l->weight()+r->weight(); 63 lc=l; 64 rc=r; 65 } 66 67 int weight(){ return wgt; } 68 69 bool isLeaf(){ return false; } 70 71 HuffNode<Elem>* left()const{ return lc; } 72 73 void setLeft(HuffNode<Elem> *b){ lc=(HuffNode*)b; } 74 75 HuffNode<Elem>* right()const{ return rc; } 76 77 void setRight(HuffNode<Elem> *b){ rc=(HuffNode*)b; } 78 }; 79 80 template<class Elem> 81 class HuffTree{ 82 private: 83 HuffNode<Elem> *theRoot; 84 public: 85 HuffTree(Elem &val,int frep){ 86 theRoot=new LeafNode<Elem>(val,frep); 87 } 88 89 HuffTree(HuffTree<Elem> *l,HuffTree<Elem> *r){ 90 theRoot=new IntlNode<Elem>(l->root(),r->root()); 91 } 92 93 ~HuffTree(){} 94 95 HuffNode<Elem>* root(){ return theRoot; } 96 97 int weight(){ return theRoot->weight(); } 98 }; 99 100 template<class Elem> 101 class HHCompare{ 102 public: 103 static bool lt(HuffTree<Elem> *x,HuffTree<Elem> *y){ 104 return x->weight()<y->weight(); 105 } 106 107 static bool eq(HuffTree<Elem> *x,HuffTree<Elem> *y){ 108 return x->weight()==y->weight(); 109 } 110 111 static bool gt(HuffTree<Elem> *x,HuffTree<Elem> *y){ 112 return x->weight()>y->weight(); 113 } 114 }; 115 116 template<class Elem> 117 HuffTree<Elem>* buildHuff(SLlist<HuffTree<Elem>*,HHCompare>* fl){ 118 HuffTree<Elem> *temp1,*temp2,*temp3; 119 for(fl->setStart();fl->leftLength()+fl->rightLength()>1;fl->setStart()){ 120 fl->remove(temp1); 121 fl->remove(temp2); 122 temp3=new HuffTree<Elem>(temp1,temp2); 123 fl->insert(temp3); 124 delete temp1; 125 delete temp2; 126 } 127 return temp3; 128 }