首先构造公共基类,因为包含纯虚函数,所以是虚基类
View Code
1 #pragma once 2 3 class IntSet{ 4 public: 5 virtual int size()=0; 6 virtual void report(int *v)=0; 7 virtual void insert(int t)=0; 8 };
基于数组的实现:
View Code
1 #include "IntSet.h" 2 3 class IntSetArray:public IntSet{ 4 int n,*x; 5 public: 6 IntSetArray(int size,int max):n(0),x(new int[size+1])//!!!size+1 7 { 8 x[0]=max; 9 } 10 ~IntSetArray(){delete []x;} 11 int size(){return n;} 12 void insert(int t) 13 { 14 int i=-1; 15 while(t>x[++i]){} 16 if(t==x[i]) 17 return; 18 /*t<x[i]*/ 19 for(int j=n;j>=i;--j) 20 x[j+1]=x[j]; 21 x[i]=t; 22 ++n;//!!! ++n 23 } 24 void report(int *v) 25 { 26 for(int i=0;i<n;++i) 27 v[i]=x[i]; 28 } 29 };
基于链表的实现:
View Code
1 #include "IntSet.h" 2 3 class IntSetList:public IntSet{ 4 struct node{ 5 int val; 6 node *next; 7 node(int val,node *next):val(val),next(next){} 8 }; 9 int n; 10 node *sentinel,*head; 11 node *rinsert(node *p,int t) 12 { 13 if(t>p->val) 14 p->next=rinsert(p->next,t); 15 else if(t<p->val) 16 { 17 p=new node(t,p); 18 ++n; 19 } 20 /*if t==p->val then do nothing */ 21 return p; 22 } 23 void releaseList(node *p) 24 { 25 if(p==sentinel) 26 return; 27 releaseList(p->next); 28 delete p; 29 } 30 public: 31 IntSetList(int size,int max):n(0),sentinel(new node(max,0)),head(sentinel){}//*** 32 ~IntSetList()//递归释放空间 33 { 34 releaseList(head); 35 delete sentinel; 36 } 37 int size(){return n;} 38 void insert(int t) 39 { 40 head=rinsert(head,t); 41 } 42 void report(int *v) 43 { 44 int i=0; 45 for(node *p=head;p!=sentinel;p=p->next) 46 v[i++]=p->val; 47 } 48 };
基于二叉查找树(BST)的实现:
View Code
1 #include "IntSet.h" 2 3 class IntSetBST:public IntSet{ 4 int n,vn; 5 int *v; 6 struct node{ 7 int val; 8 node *left,*right; 9 node(int val):val(val),left(0),right(0){} 10 }; 11 node *root; 12 node *rinsert(node *p,int t) 13 { 14 if(p==0) 15 { 16 p=new node(t); 17 ++n; 18 } 19 if(t>p->val) 20 p->right=rinsert(p->right,t); 21 else if(t<p->val) 22 p->left=rinsert(p->left,t); 23 return p; 24 } 25 void traverse(node *p)//IntSetBST中v和vn的作用仅仅是为了减少traverse的参数,否则要传递int *v和int *pvn 26 { 27 if(p==0)//*** 28 return; 29 traverse(p->left); 30 v[vn++]=p->val; 31 traverse(p->right); 32 } 33 void releaseBST(node *p)//后序释放 34 { 35 if(p==0) 36 return; 37 releaseBST(p->left); 38 releaseBST(p->right); 39 delete p; 40 } 41 public: 42 IntSetBST(int size,int max):n(0),root(0){} 43 ~IntSetBST() 44 { 45 releaseBST(root); 46 } 47 int size(){return n;} 48 void insert(int t) 49 { 50 root=rinsert(root,t); 51 } 52 void report(int *v) 53 { 54 this->v=v; 55 vn=0; 56 traverse(root); 57 } 58 };
基于位向量的实现:
View Code
1 #include "IntSet.h" 2 3 class IntSetBitVec:public IntSet{ 4 enum {BITSPERWORD=32,SHIFT=5,MASK=0x1f}; 5 int n,*vec,max; 6 void set(int i){vec[i>>SHIFT]|=1<<(i&MASK);} 7 void clr(int i){vec[i>>SHIFT]&=~1<<(i&MASK);} 8 bool test(int i){return vec[i>>SHIFT]&1<<(i&MASK);} 9 public: 10 IntSetBitVec(int size,int max):n(0),vec(new int[max/BITSPERWORD+1]),max(max) 11 { 12 for(int i=0;i<max;++i) 13 clr(i); 14 } 15 ~IntSetBitVec() 16 { 17 delete []vec; 18 } 19 int size(){return n;} 20 void insert(int t) 21 { 22 if(test(t)) 23 return; 24 set(t); 25 ++n; 26 } 27 void report(int *v) 28 { 29 int j=0; 30 for(int i=0;i<max;++i) 31 if(test(i)) 32 v[j++]=i; 33 } 34 };
基于桶(Bin)结构的实现:
View Code
1 #include "IntSet.h" 2 3 class IntSetBins:public IntSet{ 4 int n,max,Size; 5 struct node{ 6 int val; 7 node *next; 8 node(int val,node *next):val(val),next(next){} 9 }; 10 node **bins,*sentinel; 11 node *rinsert(node *p,int t) 12 { 13 if(t>p->val) 14 p->next=rinsert(p->next,t); 15 else if(t<p->val) 16 { 17 p=new node(t,p); 18 ++n; 19 } 20 return p; 21 } 22 void releaseList(node *p) 23 { 24 if(p==sentinel) 25 return; 26 releaseList(p->next); 27 delete p; 28 } 29 public: 30 IntSetBins(int Size,int max):sentinel(new node(max,0)),bins(new node*[Size]),n(0),Size(Size),max(max) 31 { 32 for(int i=0;i<Size;++i) 33 bins[i]=sentinel; 34 } 35 ~IntSetBins() 36 { 37 for(int i=0;i<Size;++i) 38 releaseList(bins[i]); 39 delete []bins; 40 delete sentinel; 41 } 42 int size(){return n;} 43 void insert(int t) 44 { 45 int i=t/(max/Size+1); 46 bins[i]=rinsert(bins[i],t); 47 } 48 void report(int *v) 49 { 50 int j=0; 51 for(int i=0;i<Size;++i) 52 for(node *p=bins[i];p!=sentinel;p=p->next) 53 v[j++]=p->val; 54 } 55 };
测试程序源码:
View Code
1 #include "IntSet.h" 2 #include "IntSetArray.h" 3 #include "IntSetList.h" 4 #include "IntSetBST.h" 5 #include "IntSetBins.h" 6 #include "IntSetBitVec.h" 7 #include <cstdlib> 8 #include <ctime> 9 #include <iostream> 10 using namespace std; 11 int main() 12 { 13 int n,m; 14 cin>>n>>m; 15 int *v=new int[m]; 16 IntSet *ss[5]={new IntSetArray(m,n),new IntSetList(m,n),new IntSetBST(m,n),new IntSetBins(m,n),new IntSetBitVec(m,n)}; 17 srand(time(NULL)); 18 for(int i=0;i<5;++i) 19 { 20 while(ss[i]->size()<m) 21 ss[i]->insert(rand()%n); 22 ss[i]->report(v); 23 cout<<"i:"<<i<<endl; 24 for(int i=0;i<m;++i) 25 cout<<v[i]<<" "; 26 cout<<endl; 27 } 28 delete []v; 29 for(int i=0;i<5;++i)//!!! not delete []ss 30 delete ss[i]; 31 return 0; 32 }