目录

栈的定义

概念

栈的抽象数据类型定义

顺序栈的基本操作

存储方式

顺序栈的表示

顺序栈的初始化

顺序栈判断是否为空

清空顺序栈

销毁顺序栈

顺序栈的入栈

顺序栈的出栈

取顺序栈的栈顶元素

链栈的基本操作

链栈的表示

链栈的初始化

判断链栈是否为空

链栈的入栈

链栈的出栈

取栈顶元素

栈与递归

分治法求解递归问题算法的一般形式

尾递归转变为循环结构

单向递归转变为循环结构


栈的定义

概念

栈 (stack) 是限定仅在表尾进行插入或删除操作的线性表。 因此, 对栈来说, 表尾端有其特殊含义, 称为栈顶 (top), 相应地, 表头端称为栈底 (bottom)。 不含元素的空表称为空栈。

栈又称为后进先出 (Last In First Out, LIFO) 的线性表。

栈的抽象数据类型定义

ADT Stack {

数据对象:

D = {ai | ai ∈ElemSet , i = 1,2,...,n,n≥0 }

数据关系:

R1 = { <ai-1, ai > | ai-1, ai ∈ D, i=2,...,n }

约定an端为栈顶,a1端为栈底。

基本操作:初始化、进栈、出栈、取栈顶元素等

}ADT Stack

顺序栈的基本操作

存储方式

同一般线性表的顺序存储结构完全相同。

利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。栈底一般在低地址端。

· 附设top指针,指示栈顶元素在顺序栈中的位置。

· 另设base指针,指示栈底元素在顺序栈中的位置。

(但是,为了方便操作,通常top指示真正栈顶元素之上的下标地址。)

· 另外,用stacksize表示栈可使用的最大容量。

空栈:base==top是栈空标志。

栈满:top-base==stacksize。

下图所示栈中元素和栈指针之间的关系

顺序栈的表示

#define MAXSIZE 100
typedef struct {SElemType *base; // 栈底指针SElemType *top;  // 栈顶指针int stacksize;   // 栈可用最大容量
} SqStack;

顺序栈的初始化

Status InitStack(SqStack &S) {    // 构造一个空栈S.base = new SElemType[MAXSIZE];    // 或S.base = (SElemType*)malloc(MAXSIZE*sizeof(SelemType));if (!S.base)    exit(OVERFLOW);     // 存储分配失败S.top = S.base;                     // 栈顶指针等于栈底指针S.stacksize = MAXSIZE;return OK;
}

顺序栈判断是否为空

栈顶指针等于栈底指针,就认为顺序栈为空

Status StackEmpty(SqStack S) {// 若栈为空,返回TRUE;否则返回FALSE    if (S.top == S.base)return TRUE;elsereturn FALSE;
}

清空顺序栈

清空顺序栈就是将栈顶指针移到栈底指针。

Status ClearStack(SqStack S) {if(S.base)   S.top = S.base;return OK;
}

销毁顺序栈

Status DestroyStack(SqStack &S) {if(S.base) {delete S.base;S.stacksize = 0;S.base = S.top = NULL;}return OK;
}

顺序栈的入栈

① 判断是否栈满,若满则出错(上溢)。

② 元素e压入栈顶。

③ 栈顶指针加1。

Status Push(SqStack &S, SElemType e) {if(S.top - S.base == S.stacksize)    // 栈满return ERROR;*S.top++=e;            // 可以分开写,*S.top=e;S.top++;return OK;
}

顺序栈的出栈

① 判断是否栈空,若空则出错(下溢)。

② 获取栈顶元素e。

③ 栈顶指针减1。

Status Pop(SqStack &S, SElemType &e) {// 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERRORif(S.top == S.base)    // 等价于if(StackEmpty(S))return ERROR;e = *--S.top;          // 可分解为两步--S.top; e = *S.top;return OK;
}

取顺序栈的栈顶元素

SElemType GetTop(SqStack S) {// 返回S的栈顶元素,不修改栈顶指针if(S.top != S.base)    // 栈非空return *(S.top-1)  // 返回栈顶元素的值,栈顶指针不变
}

链栈的基本操作

链栈的表示

链栈是运算受限的单链表,只能在链表头部进行操作。

· 链表的头指针就是栈顶。

· 不需要头结点。

· 基本不存在栈满的情况。

· 空栈相当于头指针指向空。

· 插入和删除仅在栈顶处执行。

注意:链栈中的指针方向。

typedef struct StackNode {SElemType data;struct StackNode *next;
} StackNode, *LinkStack;
LinkStack S;

链栈的初始化

void InitStack(LinkStack &S) {// 构造一个空栈,栈顶指针置为空S=NULL;return OK;
}

判断链栈是否为空

Status StackEmpty(LinkStack S) {if(S==NULL) return TRUE;else return FALSE;
}

链栈的入栈

Status Push(LinkStack &S, SElemType e) {p = new StackNode;        // 生成新结点pp -> data = e;            // 将新结点数据域置为ep -> next = S;            // 将新结点插入栈顶S = p;                    // 修改栈顶指针return OK;
}

链栈的出栈

Status Pop(LinkStack &S, SElemType &e) {if (S == NULL) return ERROR;e = S -> data;p = S;S = S -> next;delete p;return OK;
}

取栈顶元素

SElemType GetTop(LinkStack S) {if (S != NULL)return S -> data;
}

栈与递归

分治法求解递归问题算法的一般形式

void p (参数表) {if(递归结束条件) 可直接求解步骤;     ----- 基本项else p(较小的参数);                 -----归纳项
}

例如

long Fact(long n) {if(n == 0) return 1;          // 基本项else return n * Fact(n-1);    // 归纳项
}

尾递归转变为循环结构

long Fact(long n) {if(n == 0) return 1;else return n * Fact(n-1);
}

以上递归可以写成循环结构

long Fact(long n) {t = 1;for(i = 1; i <= n; i++)    t = t*i;return t;
}

单向递归转变为循环结构

虽然有一处以上的递归调用语句,但各次递归调用语句的参数只和主调函数有关,相互之间参数无关,并且这些递归调用语句处于算法的最后。

long Fib(long n) {    // Fibonacci数列if(n==1||n==2) return 1;else return Fib(n-1) + Fib(n-2);
}

转换为循环结构

long Fib(long n) {if(n==1||n==2) return 1;else {t1 = 1; t2 = 1;for(i=3;i<=n;i++){t3=t1+t2;t1=t2;t2=t3;}return t3;}
}    

数据结构-栈详解(类C语言版)相关推荐

  1. 栈结构之链栈详解(C语言版)

    文章目录 前言 一.链栈的定义 二.链栈的结构 三.链栈的常用操作 结语 附录 前言 前面完成了栈结构中顺序栈的学习,下面开始对栈结构中的链栈进行学习. 一.链栈的定义 栈是限定仅在表尾进行插人或删除 ...

  2. 图之邻接矩阵详解(C语言版)

    文章目录 一.定义 二.结构 三.常用操作 结语 附录 一.定义 图的邻接矩阵是一种采用邻接矩阵数组表示顶点之间相邻关系的存储结构.设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:       ...

  3. 图遍历详解(C语言版)

    文章目录 一.定义 二.方法 1.深度优先遍历 2.广度优先遍历 三.实现 1.无向图或强连通有向图遍历 2.非连通图遍历 结语 附录 一.定义 从给定图中任意指定的顶点(称为初始点)出发,按照某种搜 ...

  4. 图之邻接表详解(C语言版)

    文章目录 一.定义 二.结构 三.常用操作 四.测试 结语 附录 一.定义 图的邻接表是一种顺序与链式存储相结合的存储方式.下面给出一个示例,以便大家能够理解邻接表这种存储方式:         无向 ...

  5. 线索二叉树详解(C语言版)

    文章目录 一.定义 二.结构 三.常用操作 结语 附录 一.定义 前面学习了二叉树,在操作过程中发现了几个问题: 问题一:二叉树如何才能实现从一个指定结点开始遍历呢?         问题二:在二叉树 ...

  6. 选择排序算法详解之C语言版

    一.算法原理 选择排序属于不稳定排序法,是一种常用的排序算法,其时间复杂度为O(n^2). 所谓的不稳定排序算法是指在一组数据中存在多个相同的数据,但是在排序之后,相同数据的前后位置会发生改变.例如有 ...

  7. 【 数据结构 】单链表的实现 - 详解(C语言版)

    目录 前言: 顺序表的缺陷: 单链表:(Single Linked List) 概念及结构: 单链表的实现: 头文件:SList.h malloc函数: free函数: 具体函数的实现:SList.c ...

  8. 【 数据结构 】顺序表的实现 - 详解(C语言版)

    目录 前言 线性表: ​ 顺序表: 概念及结构: 顺序表的实现: 头文件:SeqList.h realloc函数讲解: 具体函数的实现:SeqList.c 顺序表的初始化: 顺序表的打印: 容量的检查 ...

  9. 数据结构链表详解(c语言实现)

    链表(C语言) 绪论 单链表的实现 单链表的定义 单链表的初始化 单链表的插入删除 单链表的删除 单链表的查找 单链表的修改 单链表的建立 双向链表 循环链表 链表与顺序表的区别 总结 绪论 线性表是 ...

最新文章

  1. 北航计算机考博C语言真题_北京航空航天大学计算机考研:严厉的老父亲,教会你本事,本科非211以上就不要去了...
  2. JVM启动的时候,默认加入的属性
  3. 考研【复试技巧】如果复试时太紧张,遇到不会的问题只能凉了吗?这些技巧收下!
  4. shell文本处理工具grep
  5. Tensorflow中使用tfrecord,队列方式读取数据
  6. C# 使用 MemoryStream 将数据写入内存
  7. 机器学习第一回——初识监督学习和无监督学习
  8. 解决spring的xml文件打开没有namespace等操作选项的问题
  9. 实战快速恢复Exchange 2010误删除的邮箱
  10. SpringMVC @ControllerAdvice 注解的官方解释
  11. python 流写入文件_Python数据流写入文件
  12. Maven搭建SSM框架测试HTTP 接口
  13. 百度贴吧一键签到工具(android版)
  14. Xilinx FPGA配置clocking时钟动态相位输出
  15. 饿了么接入之饿了么首次下单测试
  16. 计算机怎么快捷截图桌面,计算机屏幕截图快捷方式是获取屏幕截图的四种方法. 如何在笔记本电脑上截图?...
  17. js实现复制图片到剪切板下载图片
  18. 【BZOJ3470】Freda’s Walk 概率与期望
  19. 会声会影无法导入.ts文件编辑解决办法
  20. 利用bat批处理做启动mongodb脚本

热门文章

  1. 记一次oracle数据库连不上处理
  2. hashmap应用场景_Java初学者进阶系列:HashMap的容量与性能
  3. mysql 降序_MySQL 8 新特性之降序索引底层实现
  4. 一个人会python能做什么_利用Python来预测一个人有没有女朋友!无所不能!
  5. jieba是python中一个重要的标准函数库_python——Jieba库整理(基础知识+实例)
  6. 通讯录新建分组功能php,微信通讯录分组怎么设置
  7. 基于HTML在线考试系统开题报告,基于JSP的在线考试系统 开题报告.doc
  8. 日光能和电池两用计算机,计算机类专业竞赛模拟试题(doc 7页)全面优秀版优秀版...
  9. python监听多个udp端口_Python的Socket编程过程中实现UDP端口复用的实例分享
  10. 安全行业中的event与incident区别