第三章:1.栈和队列 -- 栈的表示及实现

Posted AHAU航哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第三章:1.栈和队列 -- 栈的表示及实现相关的知识,希望对你有一定的参考价值。

前言:

  栈和队列 是两种重要的线性结构。从数据结构角度来看,栈和队列也是线性表,它的特殊性在于其操作是线性表的子集,是操作受限的线性表,因此可以称作限定性的数据结构。

  (限定性:如、人为的规定线性表只能从表尾插入和删除结点数据元素,那么这样的线性表就是栈)

 

目录:

  1、栈

  2、栈的应用举例

  3、栈与递归的实现

  4、队列

  5、离散事件模型

 

正文:

  栈的定义

    栈(stack) 如上所说,就是限定只能在表尾进行插入和删除的线性表。表尾 称为 栈顶(top), 表头 称为 栈底 (bottom),没有数据元素 称为 空栈

    假设栈 S=(a1, a2, a3 ... an); 那么 a1 为栈底元素,an 为栈顶元素。因为栈的修改是按照 后进先出的原则进行,因此又称栈为 后进先出(last in first out)的线性表。可用下图表示:

      

  栈的表示和实现

    栈和线性表一样也有两种表示形式

    顺序栈,即栈的顺序存储结构是利用一组地址连续的存储单元依次存放栈底到栈顶的数据元素,同时附设 base 作为栈底指针,top 作为 栈顶指针。

      一般来说,在初始化栈的时候不应该限定栈的最大容量。我们在此的做法是:先为栈分配一个基本容量,然后在应用的过程中,当栈的空间不够用的时候再逐段夸大。

      因此需设定两个常量: STACK_INIT_SIZE(初始分配量) 和 STACKINCREMENT(分配增量)

      元素和栈指针的关系图:

      

      C语言中,讲顺序栈描述如下:

      typedef struct {
          SElemType * base;
          SElemType * top;
          int stacksize;
      }SqStack;

    实现代码:

      

#include<stdio.h>
#include<stdlib.h>

#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
//Status是函数的类型,其值是函数结果状态码
typedef int Status;
typedef int SElemType;

typedef struct {
    SElemType * base;
    SElemType * top;
    int stacksize;
}SqStack;

//构造空栈
Status InitStack(SqStack &S){
    S.base=(SElemType *)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
    if(!S.base) exit(OVERFLOW);
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}

//插入元素 (入栈)
Status Push(SqStack &S,SElemType e){
    if((S.top-S.base)==S.stacksize){                                        //空间不够,继续分配空间
        S.base=(SElemType *)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
        if(!S.base) exit(OVERFLOW);
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top=e;
    S.top++;
    return OK;
}

//删除元素(出栈)
Status Pop(SqStack &S,SElemType &e){
    if(S.top!=S.base){
        e=*(--S.top);
    }else{
        return ERROR;
    }
    return OK;
}



void printAllValues(SqStack &S){
    SElemType * q=S.top;
    printf("top:%p\\n",q);
    while(q!=S.base){
        printf("地址:%p,",q-1);
        printf("值:%d\\n",*(q-1));
        q--;
    }
    printf("base:%p\\n",S.base);
}


void main(){
    SqStack S;
    if(InitStack(S)){
        printf("%s\\n","初始化空栈成功!");
    }
    
    printf("%s\\n","进行入栈操作Push:");
    Push(S,2);
    Push(S,5);
    Push(S,66);
    Push(S,31);
    printf("%s\\n","S:");
    printAllValues(S);

    printf("\\n%s\\n","出栈后:");
    SElemType e;
    Pop(S,e);
    printAllValues(S);
    printf("\\n出栈元素:%d\\n",e);
}

    运行结果:

      

 

  栈的链式表示:               

    因为栈的操作是线性表操作的子集,所以链式栈的实现比较容易,在此也不予以实现来了。

以上是关于第三章:1.栈和队列 -- 栈的表示及实现的主要内容,如果未能解决你的问题,请参考以下文章

数据结构与算法学习笔记 栈和队列Ⅰ

自定义栈的实现及使用两个栈模拟队列

(王道408考研数据结构)第三章栈和队列-第一节:栈基本概念顺序栈和链栈基本操作

栈和队列的基本概念及操作

数据结构-栈和队列精讲

数据结构与算法--栈和队列