• 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 }
  • 相关阅读:
    响应式布局
    Fiddler2汉化版使用说明
    nonmember,nonfriend替换member函数
    Java回顾之Spring基础
    dudu,想在cnblogs首页看很久以前的文章不行。
    基于Nios II内核的项目程序为什么越优化越慢?
    学习 easyui:禁用 linkbutton 问题
    Socket编程 (异步通讯,解决Tcp粘包) 3
    .NET:可扩展的单据编号生成器 之 基于缓冲区的顺序号
    淘宝API应用开发
  • 原文地址:https://www.cnblogs.com/double-win/p/3591442.html
Copyright © 2020-2023  润新知