编程珠玑Column13中5种实现整型集合(IntSet)的方式

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

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 }

 

 

你可能感兴趣的:(column)