用一维数组实现栈(C++编程思想 p120)

1 实现思路

向栈中插入4个元素后的状态

执行过程分析:

 

2 代码实现

clib.h 接口定义

 1 typedef struct CStashTag
 2 {
 3     int ele_size;                    //栈中每个元素的占用的字节数 
 4     int capacity;                    //栈的容量,栈当前(不扩展)可容纳的元素的个数
 5     int next;                        //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
 6     unsigned char* storage;            //栈存储空间字符指针,动态分配的字节数组
 7 } CStash;
 8 
 9 void initalize(CStash* s, int size);
10 void cleanup(CStash* s);
11 int add(CStash* s, const void* element);
12 void* fetch(CStash* s, int index);
13 int count(CStash* s);
14 void inflate(CStash* s, int increase = 10);

2 Clib.cpp 函数实现

  1 #include <string>
  2 #include <iostream>
  3 #include <cassert>
  4 #include "clib.h"
  5 
  6 using namespace std;
  7 
  8 void initalize(CStash* s, int sz)
  9 {
 10     s->ele_size = sz;     
 11     s->capacity = 0;  
 12     s->next = 0;
 13     s->storage = 0; 
 14 }
 15 
 16 int add(CStash* s, const void* element)
 17 {
 18     if (s->next  >=  s->capacity)
 19     {
 20         inflate(s);
 21     }
 22     int startBytes = s->next * s->ele_size;
 23     unsigned char* e = (unsigned char*)element;
 24 
 25     for (int i=0; i<s->ele_size; i++)
 26         s->storage[startBytes + i] = e[i];
 27     s->next++;
 28 
 29     return s->next - 1;
 30 }
 31 
 32 //取出索引index处的栈元素
 33 void* fetch(CStash* s, int index)
 34 {
 35     assert(0 <= index);
 36     if (index >= s->next)
 37     {
 38         return 0;
 39     }
 40     return &(s->storage[index * s->ele_size]);
 41 }
 42 
 43 //返回栈中元素的个数
 44 int count(CStash* s)
 45 {
 46     return s->next;
 47 }
 48 
 49 //扩展栈空间,增加increase个元素空间
 50 void inflate(CStash* s, int increase)
 51 {
 52     printf("inflate increase %d\n", increase);
 53 
 54     assert(increase > 0);
 55 
 56     //原栈长 + 增加的栈元素个数
 57     int newCapacity = s->capacity + increase;
 58     int newBytes = newCapacity * s->ele_size;   //新的栈空间字节数
 59     int oldBytes = s->capacity * s->ele_size;        //旧的栈空间字节数
 60 
 61     unsigned char* b = new unsigned char[newBytes]; //在堆上分配新的栈空间
 62 
 63     if (oldBytes) 
 64     {
 65         //拷贝旧的栈空间的内容到新的栈空间,并释放旧的栈空间
 66         //把旧内存块中的数据拷贝到新分配的内存块
 67         for (int i=0; i<oldBytes; i++)
 68             b[i] = s->storage[i];
 69         delete [] (s->storage); //释放旧的内存块
 70     }
 71 
 72 
 73     s->storage = b; //使栈存储空间字符指针s->storage指向新分配的内存块
 74     s->capacity = newCapacity; //更新栈的容量
 75 }
 76 
 77 
 78 //清理栈存储空间字符指针
 79 void cleanup(CStash* s)
 80 {
 81     if (s->storage != 0)
 82     {
 83         cout<<"freeing storage"<<endl;
 84         delete []s->storage;
 85     }
 86 }
 87 
 88 
 89 int main(int argc, char* argv[])
 90 {
 91 
 92     CStash stash;
 93 
 94     char str1[] = "d1111";
 95     char str2[] = "d2222";
 96     char str3[] = "d3333";
 97     char str4[] = "d4444";
 98 
 99     initalize(&stash, 20);
100 
101     add(&stash, str1);
102     add(&stash, str2);
103     add(&stash, str3);
104     add(&stash, str4);
105 
106     unsigned char* result = (unsigned char*)fetch(&stash, 2);
107     printf("fetch result %s\n", result);
    
     cleanup(&stash);
108 109 return 0; 110 };


输出:

inflate increase 10
fetch result d3333

freeing storage

 

向栈中存放int型数据测试:

 1 void intTest() 
 2 {
 3     CStash intStash;
 4     
 5     initalize(&intStash, sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节
 6 
 7     int i;
 8     for (i=0; i<20; i++)
 9         add(&intStash, &i);
10 
11     for (i=0; i<count(&intStash); i++)
12         cout<< "fetch(&intStash, " << i << ") = " << *(int *) fetch(&intStash, i) <<endl;
13     cleanup(&intStash);
14 }

输出:

inflate increase 10
inflate increase 10
fetch(&intStash, 0) = 0
fetch(&intStash, 1) = 1
fetch(&intStash, 2) = 2
fetch(&intStash, 3) = 3
fetch(&intStash, 4) = 4
fetch(&intStash, 5) = 5
fetch(&intStash, 6) = 6
fetch(&intStash, 7) = 7
fetch(&intStash, 8) = 8
fetch(&intStash, 9) = 9
fetch(&intStash, 10) = 10
fetch(&intStash, 11) = 11
fetch(&intStash, 12) = 12
fetch(&intStash, 13) = 13
fetch(&intStash, 14) = 14
fetch(&intStash, 15) = 15
fetch(&intStash, 16) = 16
fetch(&intStash, 17) = 17
fetch(&intStash, 18) = 18
fetch(&intStash, 19) = 19
freeing storage

 

向栈中存放字符串(字符数组指针)测试:

 1 void stringTest()
 2 {
 3     CStash  stringStash;
 4 
 5 
 6     ifstream in;
 7 
 8     
 9     const int bufsize = 80;
10     initalize(&stringStash, sizeof(char) * bufsize);
11     in.open("clib.h");
12     assert(in);
13 
14     string line;
15     while (getline(in, line))
16     {
17         add(&stringStash, line.c_str());
18     }
19 
20     char *cp;
21     int i = 0;
22     while ((cp = (char *) fetch(&stringStash, i++)) != 0)
23     {
24         cout<< "fetch(&stringStash, " << i << ") = " << cp << endl;
25     }
26 
27     cleanup(&stringStash);
28 }

输出:

inflate increase 10
inflate increase 10
fetch(&stringStash, 1) = typedef struct CStashTag
fetch(&stringStash, 2) = {
fetch(&stringStash, 3) = int ele_size;       //栈中每个元素的占用的字节数
fetch(&stringStash, 4) = int capacity;       //栈的容量,栈当前(不扩展)可容纳的元素的个数
fetch(&stringStash, 5) = int next;         //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
fetch(&stringStash, 6) = unsigned char* storage; //栈存储空间字符指针,动态分配的字节数组
fetch(&stringStash, 7) = } CStash;
fetch(&stringStash, 8) =
fetch(&stringStash, 9) = void initalize(CStash* s, int size);
fetch(&stringStash, 10) = void cleanup(CStash* s);
fetch(&stringStash, 11) = int add(CStash* s, const void* element);
fetch(&stringStash, 12) = void* fetch(CStash* s, int index);
fetch(&stringStash, 13) = int count(CStash* s);
fetch(&stringStash, 14) = void inflate(CStash* s, int increase = 10);
freeing storage

 

附C++实现:

1)Stash.h头文件

 1 #ifndef STASH_H_INCLUDED
 2 #define STASH_H_INCLUDED
 3 
 4 class Stash
 5 {
 6     int ele_size;                    //栈中每个元素的占用的字节数
 7     int capacity;                    //栈的容量,栈当前(不扩展)可容纳的元素的个数
 8     int next;                        //相当于栈指针(标记下一个空位索引),栈中当前元素的个数
 9     unsigned char* storage;            //栈存储空间字符指针,动态分配的字节数组
10     void inflate(int increase = 10);
11 
12 public:
13     void initalize(int sz);
14     int add(const void* element);
15     void* fetch(int index);
16     int count();
17     void cleanup();
18 };
19 
20 #endif // STASH_H_INCLUDED

2)Stash.cpp实现文件

 1 #include "Stash.h"
 2 #include <iostream>
 3 #include <cassert>
 4 
 5 using namespace std;
 6 
 7 void Stash::initalize(int sz)
 8 {
 9     ele_size = sz;
10     capacity = 0;
11     next = 0;
12     storage = 0;
13 }
14 
15 
16 int Stash::add(const void *element)
17 {
18     if (next >= capacity)
19     {
20         inflate();
21     }
22 
23     int startBytes = next * ele_size;
24     unsigned char *e = (unsigned char *) element;
25 
26     for (int i=0; i<ele_size; i++)
27     {
28         storage[startBytes + i] = e[i];
29     }
30     next++;
31 
32     return next-1;
33 }
34 
35 void Stash::inflate(int increase)
36 {
37     cout << "inflate increase: " << increase << endl;
38 
39     assert(increase > 0);
40 
41     int newCapacity = capacity + increase;
42     int newBytes = newCapacity * ele_size;
43     int oldBytes = capacity * ele_size;
44 
45     unsigned char *b = new unsigned char[newBytes];
46 
47     if (oldBytes)
48     {
49         for (int i=0; i<oldBytes; i++)
50             b[i] = storage[i];
51         delete []storage;
52     }
53 
54     storage = b;
55     capacity = newCapacity;
56 }
57 
58 void* Stash::fetch(int index)
59 {
60     assert(index >= 0);
61     if (index > next)
62         return 0;
63     return &(storage[index * ele_size]);
64 }
65 
66 int Stash::count()
67 {
68     return next;
69 }
70 
71 void Stash::cleanup()
72 {
73     if (storage != 0)
74     {
75         cout << "freeing storage .... " << endl;
76         delete []storage;
77     }
78 }

 

3)main.cpp测试类

 1 #include <iostream>
 2 #include <string>
 3 #include <fstream>
 4 #include "Stash.h"
 5 
 6 using namespace std;
 7 
 8 
 9 void intTest()
10 {
11     Stash intStash;
12 
13     intStash.initalize(sizeof(int)); //栈中存放int型数据,所以栈元素占用int--4个字节
14 
15     int i;
16     for (i=0; i<20; i++)
17         intStash.add(&i);
18 
19     for (i=0; i<intStash.count(); i++)
20         cout<< "intStash.fetch(" << i << ") = " << *(int *) intStash.fetch(i) <<endl;
21     intStash.cleanup();
22 }
23 
24 void stringTest()
25 {
26     Stash  stringStash;
27     ifstream in;
28     const int bufsize = 80;
29 
30     stringStash.initalize(sizeof(char) * bufsize);
31     in.open("Stash.h");
32 
33     string line;
34     while (getline(in, line))
35     {
36         stringStash.add(line.c_str());
37     }
38 
39     char *cp;
40     int i = 0;
41     while ((cp = (char *) stringStash.fetch(i++)) != 0)
42     {
43         cout<< "stringStash.fetch(" << i << ") = " << cp << endl;
44     }
45 
46     stringStash.cleanup();
47 }
48 
49 
50 int main()
51 {
52 
53     //intTest();
54     stringTest();
55 
56     return 0;
57 }

 

posted @ 2015-06-07 19:40  asnjudy  阅读(605)  评论(0编辑  收藏  举报