数据结构-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 }
posted @ 2024-03-01 15:13  kitsum  阅读(6)  评论(0编辑  收藏  举报