第三章: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);
}

    运行结果:

      

  栈的链式表示:               

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

时间: 2024-10-08 00:59:11

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

第4章 栈与队列-----栈

栈 (stack)是限定仅在表尾进行插入和删除操作的线性表.   允许插入和删除的一端称为栈顶(top),另一端为栈底(bottom),不含任何数据元素的栈称为空栈.栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构. 栈的抽象数据类型   实例:StaticSize是5,则栈普通情况.空栈和栈满的情况示意图如图4-4-2所示   栈的顺序存储结构----进栈操作 栈的顺序存储结构---出栈操作  栈的链式存储结构,简称链栈   栈的链式存储结构---进栈操作 栈的

第三章:2.栈和队列 -- 栈的应用举例

前言: 本节为栈的应用举例,只包括代码实现部分 目录: 2.栈的应用举例 进制转换: 括号匹配: 正文: 进制转换实现代码: 注意:此函数要和上一节,栈的实现代码放在一起 //进制转换 void conversion(){ SqStack S; InitStack(S); int num; printf("%s","请输入一个十进制数:"); scanf("%d",&num); while(num){ Push(S,num%8); num

数据结构-王道2017-第3章 栈和队列-栈和队列的应用

1.前中后缀表达式的转换: 举例说明将自然表达式转换成二叉树: a×(b+c)-d ① 根据表达式的优先级顺序,首先计算(b+c),形成二叉树 ②然后是a×(b+c),在写时注意左右的位置关系 ③最后在右边加上 -d 然后最这个构造好的二叉树进行遍历,三种遍历的顺序分别是这样的: ① 前序遍历:根-左-右 ② 中序遍历:左-根-右 ③ 后序遍历:左-右-根 前缀表达式:-*a+bcd 中缀表达式:a*b+c-d 后缀表达式:abc+*d- 2.队列在层次遍历二叉树中起作用,且在计算机系统中应用非

剑指offer-面试题9-用两个栈实现队列-栈和队列

/* 题目: 用两个栈实现一个队列.队列声明如下. */ /* 思路: 将值压入stack1,再从stack1弹出到stack2,则为先进先出. appendTail时直接压入stack1即可,当stack2没有可用于deleteHead的元素时,将stack1的元素全部压入stack2. */ template<typename T> class CQueue{ public: CQueue(void) ~CQueue(void); void appendTail(const T&

剑指offer-用两个栈实现队列-栈和队列-python

题目描述 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. # -*- coding:utf-8 -*- class Solution: def __init__(self): self.stack1 = [] self.stack2 = [] def push(self, node): # write code here self.stack1.append(node) return self.stack1 def pop(self): # return x

05 1 栈与队列 栈的实现与Stack类

1 /// <summary> 2 /// 自定义栈 3 /// </summary> 4 class CStack { 5 6 /// <summary> 7 /// 存储数据的数组 8 /// </summary> 9 private ArrayList m_arrayList; 10 /// <summary> 11 /// 栈顶索引 12 /// </summary> 13 private int m_top; 14 15 p

数据结构期末复习第三章栈和队列

第三章:栈和队列 栈的特性:后进先出(LIFO) 1.  输入序列为ABC,可以变为CBA时,经过的栈操作为( B )A. push, pop, push, pop, push, popB. push, push, push, pop, pop, popC. push, push, pop, pop, push, popD. push, pop, push, push, pop, pop 解析: ABC经过push,push,push操作后,从栈顶到栈底元素为CBA,经过pop,pop,pop出

第三章小结--栈与队列

第三章小结 第三章我们主要学习了栈和队列.经过第一次的写博客,与课后的学习与借鉴.我看到很多其他的同学在整理知识的时候采用了画大纲图,架构图的方法.不得不说,那样子确实比纯粹的文字更加简单明了.于是我决定也学习和效仿一下. 以下便是图解: 通过大图来看,很明显,和前面学习的顺序表,链表栈和队列的操作有同工异曲之妙.实际上围绕着栈和队列的也是分为两大分支,顺序表和链表.操作也是从初始化,插入,删除,查找几个操作入手. 当然,也有不同的地方,栈是典型的先进而后出,队列则是先进先出,其插入和删除的操作

剑指offer-第二章数据结构(数组,字符串,链表,树,栈与队列)及例题

一.数组(最简单的数据结构) 定义:占据一块连续内存并按照顺序存储数据.创建时先指定大小,分配内存. 优点:时间效率高.实现简单的hash(下标为key,对应的数据为value) 缺点:空间效率差.如果我们只在数组中存一个数字,也先分配所有的内存. 扩展:动态数组(解决空间效率差),手段:扩容后,复制内容到新的数组,释放之前的内存.时间性能变差,因此,要尽量减少改变数组容量的次数. 数组与指针:声明一个数组时,数组名字也是一个指针,指向数组的第一个元素. 例题:在一个二维数组中,每一行都按照从左