首先构造公共基类,因为包含纯虚函数,所以是虚基类

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 }

 

 

posted on 2013-03-24 15:45  particle  阅读(574)  评论(0编辑  收藏  举报