1. 栈的顺序存储实现

根据清华大学出版社《数据结构(C语言版)》第三章所述,栈是限定仅在表尾进行插入或删除操作的线性表(其本质还是一个线性表)。其特性是数据入口和出口都是同一个,因此遵循“先入后出”的特性。

既然是一个线性表,而且入口和出口相同,那么该结构需要有以下的数据属性:

1.  栈底指针(struct Stack*base),栈的存储首地址。

2.  栈顶指针(struct Stack *top),可以看成是一个游标,该指针所指向的位置始终指向栈中最新存入数据的下一位(前提是*base存储的是栈的首个元素)。

3.  栈的大小(ElemType size), 表示栈的深度,一般为一个常量。

----------------------------------------------------------------------------------------------------

栈作为特殊的线性表,继承了线性表的部分操作。

1. 构建栈(InitStack)。

2. 销毁栈 (DestroyStack)。

3. 插入数据(Push)。

4. 弹出数据(Pop)。

5. 清空栈 (ClearStack)。

6. 获取栈顶元素(GetTop)。

还有辅助操作:

----------------------------------------------------------------------------------------------------

7. 栈是否为空(IsEmpty)。

8. 栈是否已满(IsFull)。

 

具体实现如下:

  1 #include <iostream>
  2 using namespace std;
  3 
  4 #define STACK_SIZE 100
  5 struct Stack
  6 {
  7        int *top;
  8        int *base;
  9        int size;
 10 }Stack;
 11 
 12 /***********************************
 13 * Function Statements
 14 ***********************************/
 15 bool InitStack(struct Stack &S);
 16 bool IsEmpty(struct Stack &S);
 17 bool IsFull(struct Stack &S);
 18 void Push(struct Stack &S, int e);
 19 void Pop(struct Stack &S, int &e);
 20 bool DestroyStack(struct Stack &S);
 21 bool ClearStack(struct Stack &S);
 22 void printStack(struct Stack &S); 
 23 
 24 
 25 int main()
 26 {
 27     struct Stack S;
 28     int b,n;
 29     if(InitStack(S)==false)
 30     {
 31         cout<<"Init Stack error!"<<endl;
 32         exit(0);
 33     }
 34     cout<<"push a data into stack:"<<endl;
 35     
 36     n=8;
 37     
 38     //压栈 
 39     cout<<"压栈操作"<<endl;
 40     while(n--)
 41     {
 42        Push(S,n);
 43        printStack(S);
 44     }
 45     
 46     //弹栈
 47     cout<<"弹栈操作"<<endl;
 48     while(n<4)
 49     {
 50       Pop(S,b);
 51       printStack(S);
 52       n++;
 53     }
 54     
 55     // 清栈 
 56     cout<<"清空栈操作:"<<endl;
 57     if(ClearStack(S))
 58         printStack(S);
 59     
 60     //销毁栈
 61     
 62     cout<<"销毁栈操作:"<<endl; 
 63     DestroyStack(S);
 64     cout<<"S.base = "<<S.base<<" S.top = "<<S.top<<" S.size= "<<S.size<<endl; 
 65     system("pause");
 66     return 0;
 67     
 68 }
 69 
 70 /********************************************************
 71  * printStack 
 72  * 打印栈中的元素,自顶向下显示 
 73 ********************************************************/
 74 void printStack(struct Stack &S)
 75 {
 76      int n = S.top-S.base;
 77      int index;
 78      if(n==0)
 79      {
 80          cout<<".................................."<<endl;
 81          cout<<"Stack is Empty..."<<endl;
 82          cout<<".................................."<<endl;
 83          return;
 84      }
 85      cout<<".................................."<<endl;
 86      cout<<"栈中的数据(从栈顶元素开始向下显示)"<<endl; 
 87      for(index=1;index<=n;++index)
 88      {
 89         cout<<*(S.top - index)<<" ";
 90      }
 91      cout<<endl;
 92 }
 93 
 94 /********************************************************
 95  * InitStack
 96  * 动态分配内存 
 97  * 并对栈的属性初始化 
 98 ********************************************************/
 99 bool InitStack(struct Stack &S)
100 {
101      S.base = (int* )malloc(STACK_SIZE *sizeof(Stack));
102      if(NULL == S.base)
103      {
104              cout<<"malloc stack error!"<<endl;
105              return false;
106      }
107      S.top = S.base; // init stack is empty
108      S.size = STACK_SIZE; 
109      return true;
110 }
111 
112 /********************************************************
113  * ClearStack 
114  * 清空栈内数据 
115 ********************************************************/
116 bool ClearStack(struct Stack &S)
117 {
118      S.top = S.base;
119      return true;
120 }
121 
122 /********************************************************
123  * DestroyStack 
124  * 销毁栈S,释放内存,并将指针属性置空,防止悬浮指针产生 
125 ********************************************************/
126 bool DestroyStack(struct Stack &S)
127 {
128      free(S.base);
129      S.base =NULL; // 防止悬浮指针 
130      S.top = NULL; // 防止悬浮指针 
131      S.size =0;
132      return true;
133 }
134 
135 /********************************************************
136  * IsEmpty 
137  * 判断栈是否为空
138  *     若栈顶指针(S.top)和栈底指针(S.base)相等
139  *     则表示站内没有数据 
140 ********************************************************/
141 bool IsEmpty(struct Stack &S)
142 {
143      if(S.top == S.base) return true;
144      else return false;
145 }
146 
147 /********************************************************
148  * IsFull 
149  * 判断栈是否存满了数据 
150  *     A = S.top - S.base 表示栈中当前实际存储了多少元素
151  *     B = S.size 则表示栈的容量。 
152  *     若A>=B,则表示栈溢出 
153 ********************************************************/
154 bool IsFull(struct Stack &S)
155 {
156      if((S.top-S.base) >= STACK_SIZE) 
157      {
158         cout<<"Stack is Full"<<endl;
159         return true;
160      }
161      else return false;
162 }
163 /********************************************************
164  * Push 
165  * 压栈操作 
166  *     栈是特殊的线性表,其不支持随机访问,因此只能按照顺序存储。 
167  *     例如:子弹夹上子弹(该例子与本实现不同的是
168  *            ++子弹夹栈顶指针保持不变,栈底指针游动。
169  *            ++本程序实现的是栈底指针不变,栈顶指针游动。) 
170 ********************************************************/
171 void Push(struct Stack &S, int e)
172 {
173      if(!IsFull(S))
174      {
175          *(S.top) = e;
176          S.top ++;
177      }
178 }
179 /********************************************************
180  * Push 
181  * 弹栈操作 
182  *     栈是特殊的线性表,其不支持随机访问,因此只能按照顺序存储。 
183  *     例如:子弹夹推出子弹(该例子与本实现不同的是
184  *            ++子弹夹栈顶指针保持不变,栈底指针游动。
185  *            ++本程序实现的是栈底指针不变,栈顶指针游动。) 
186 ********************************************************/
187 void Pop(struct Stack &S, int &e)
188 {
189      if(IsEmpty(S))
190      {
191         cout<<"Pop error"<<endl;
192      }
193      else
194      {
195          e = *(S.top-1);
196          S.top --;
197      }
198 }
posted @ 2014-03-10 11:37  Double_win  阅读(1523)  评论(0编辑  收藏  举报