Fork me on GitHub

数据结构与算法——栈 特点与算法实现

1. 栈的特点

有一个胡同很窄只能通过一辆车,而且是死胡同,只能从胡同口进出,如果第一个进入,出去会很麻烦,需要所有的车辆出去后才能出去,如图:

胡同里的小汽车是排成一条直线,是线性排列,而且只能从一端进出,后进的汽车先出去,后进 先出(Last In First Out,LIFO),这就是"栈"。栈也是一种线性表,只不过它是操作受限的线性 表,只能在一端操作。 进出的一端称为栈顶(top),另一端称为栈底(base)。栈可以用顺序存储,也可以用链式存储。 我们先看顺序存储方式:

 

其中,base 指向栈底,top 指向栈顶。

注意:栈只能在一端操作,后进先出,这是栈的关键特征,也就是说不允许在中间查找、取值、插入、删除等 操作,我们掌握好顺序栈的初始化、入栈,出栈,取栈顶元素等操作即可。

 

2.栈的算法实现

2.1 栈数据结构的定义

1 #define MaxSize 128        //预先分配空间,这个数值根据实际需要预估确定
2 
3 typedef int ElemType;
4 
5 typedef struct _SqStack
6 {
7     ElemType *base; //栈底指针
8     ElemType *top; //栈顶指针
9 }SqStack;

 

2.2 栈的初始化

 1 bool InitStack(SqStack &S)            //构造一个空栈 S
 2 {
 3     S.base = new int[MaxSize];            //为顺序栈分配一个最大容量为 Maxsize 的空间
 4 
 5     if (!S.base)                        //空间分配失败
 6         return false;
 7 
 8     S.top=S.base;                        //top 初始为 base,空栈
 9     
10     return true;
11 }

 

2.3 入栈

入栈操作:判断是否栈满,如果栈已满,则入栈失败,否则将元素放入栈顶,栈顶指针向上移动一个空间(top++)。

1 bool PushStack(SqStack &S, int e)            // 插入元素 e 为新的栈顶元素
2 {
3     if (S.top-S.base == MaxSize)            //栈满
4         return false;
5 
6     *(S.top++) = e;                            //元素 e 压入栈顶,然后栈顶指针加 1,等价于*S.top=e;  S.top++;
7 
8     return true;
9 }

 

2.4 出栈

出栈操作: 和入栈相反,出栈前要判断是否栈空,如果栈是空的,则出栈失败,否则将栈顶元素暂存给一个变 量,栈顶指针向下移动一个空间(top--)。

 1 bool PopStack(SqStack &S, ElemType &e)        //删除 S 的栈顶元素,暂存在变量e中
 2 {
 3     if (S.base == S.top)                    //栈空
 4     {
 5         return false;
 6     }
 7     e = *(--S.top); //栈顶指针减 1,将栈顶元素赋给 e
 8     
 9     return true;
10 }

 

2.5 获取栈顶元素

取栈顶元素和出栈不同,取栈顶元素只是把栈顶元素复制一份,栈的元素个数不变,而出栈是指栈顶元素取出, 栈内不再包含这个元素。

 1 ElemType GetTop(SqStack &S)                //返回 S 的栈顶元素,栈顶指针不变
 2 {
 3     if (S.top != S.base)                //栈非空
 4     {
 5         return *(S.top - 1);            //返回栈顶元素的值,栈顶指针不变
 6     }
 7     else
 8     {
 9         return -1;
10     }
11 }

 

2.6 判断是否空栈

 1 bool IsEmpty(SqStack &S)                //判断栈是否为空
 2 {
 3     if (S.top == S.base)
 4     {
 5         return true;
 6     }
 7     else
 8     {
 9         return false;
10     }
11 }

 

 

3. 完整实现

  1 #include <Windows.h>
  2 #include <iostream>
  3 #include <stdlib.h>
  4 
  5 using namespace std;
  6 
  7 #define MaxSize 128                //预先分配空间,这个数值根据实际需要预估确定
  8 
  9 typedef int ElemType;
 10 
 11 typedef struct _SqStack
 12 {
 13     ElemType *base;               //栈底指针
 14     ElemType *top;                //栈顶指针
 15 }SqStack;
 16 
 17 bool InitStack(SqStack &S)                //构造一个空栈 S
 18 {
 19     S.base = new ElemType[MaxSize];        //为顺序栈分配一个最大容量为 Maxsize 的空间
 20     if (!S.base)                //空间分配失败
 21         return false;
 22         
 23     S.top=S.base;                //top 初始为 base,空栈
 24     return true;
 25 }
 26 
 27 bool PushStack(SqStack &S, ElemType e)      //插入元素 e 为新的栈顶元素
 28 {
 29     if (S.top-S.base == MaxSize)            //栈满
 30         return false;
 31     *(S.top++) = e;                         //元素 e 压入栈顶,然后栈顶指针加 1,等价于*S.top=e;  S.top++;
 32 
 33     return true;
 34 }
 35 
 36 bool PopStack(SqStack &S, ElemType &e)      //删除 S 的栈顶元素,暂存在变量 e 中
 37 {
 38     if (S.base == S.top)                    //栈空
 39     {
 40         return false;
 41     }
 42     e = *(--S.top);                         //栈顶指针减 1,将栈顶元素赋给 e
 43 
 44     return true;
 45 }
 46 
 47 ElemType GetTop(SqStack &S)                 //返回 S 的栈顶元素,栈顶指针不变
 48 {
 49     if (S.top != S.base)                    //栈非空
 50     {
 51         return *(S.top - 1);                //返回栈顶元素的值,栈顶指针不变
 52     }
 53     else
 54     {
 55         return -1;
 56     }
 57 }
 58 
 59 int GetSize(SqStack &S)                     //返回栈中元素个数
 60 {
 61     return (S.top-S.base);
 62 }
 63 
 64 bool IsEmpty(SqStack &S)                    //判断栈是否为空
 65 {
 66     if (S.top == S.base)
 67     {
 68         return true;
 69     }
 70     else
 71     {
 72         return false;
 73     }
 74 }
 75 
 76 void DestoryStack(SqStack &S)
 77 {
 78     if(S.base)
 79     {
 80         free(S.base);
 81         S.base = NULL;
 82         S.top = NULL;
 83     }
 84 
 85 }
 86 int main()
 87 {
 88     int n,x;
 89     SqStack S;
 90     InitStack(S);                      //初始化一个顺序栈 S
 91 
 92     cout <<"请输入元素个数 n:" <<endl;
 93     cin>>n;
 94     cout <<"请依次输入 n 个元素,依次入栈:" <<endl;
 95 
 96     while(n--)
 97     {
 98         cin>>x;                        //输入元素
 99         PushStack(S, x);
100     }
101 
102     cout <<"元素依次出栈:" <<endl;
103 
104     while(!IsEmpty(S))                //如果栈不空,则依次出栈
105     {
106         cout<<GetTop(S)<<"\t";        //输出栈顶元素
107         PopStack(S, x);               //栈顶元素出栈
108     }
109 
110     cout <<endl;
111     DestoryStack(S);
112 
113     system("pause");
114     return 0;
115 }

 

posted @ 2020-10-21 17:56  索智源  阅读(383)  评论(0编辑  收藏  举报