用一维数组实现栈(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 }