数据结构与算法分析

栈模型

  • 限制插入和删除只能在表的末端的表
  • 表的末端叫做栈顶(top)
  • 支持Push进栈和Pop入栈操作
  • //LIFO后进先出表

栈的实现

链表实现

类型声明

  1. struct Node ;
  2. typedef struct Node *PtrToNode ;
  3. typedef struct Node Stack
  4. int IsEmpty(Stack S) ;
  5. Stack CreateStack(void) ;
  6. void DisposeStack(Stack S) ;
  7. void MakeEmpty(Stack S) ;
  8. void Push(ElementType X,Stack S) ;
  9. ElementType Top(Stack S) ;
  10. void Pop(Stack s) ;
  11. struct Node
  12. {
  13. ElementType Element ;
  14. PtrToNode Next ;
  15. }

检测是否为空栈

  1. void IsEmpty(Stack S)
  2. {
  3. return S->Next == NULL ;
  4. }

创建空栈

  1. Stack CreateStack(void)
  2. {
  3. Stack S ;
  4. S = malloc(sizeof(struct Node)) ;
  5. if(S == NULL)
  6. {
  7. FatalError("内存不足")
  8. }
  9. S->Next = NULL ;
  10. MakeEmpty(S) ;
  11. return S ;
  12. }
  13. void MakeEmpty(Stack S)
  14. {
  15. if(S == NULL)
  16. {
  17. Error("请先创建一个栈")
  18. }
  19. else
  20. {
  21. while(!IsEmpty(S)
  22. Pop(S) ;
  23. }
  24. }

Push进栈

  1. void Push(ElementType X, Stack S)
  2. {
  3. PtrToNode TmpCell ;
  4. TmpCell = malloc(sizeof(struct Node)) ;
  5. if(TmpCell == NULL)
  6. FaltalError("内存不足")
  7. else
  8. {
  9. TmpCell->Element = X ;
  10. TmpCell->Next = S->Next ;
  11. S->Next = TmpCell ;
  12. }
  13. }

返回top栈顶元素

  1. ElementType Top(Stack S)
  2. {
  3. if(!IsEmpty(S)
  4. return S->Next->ElementType ;
  5. Error("空栈")
  6. return 0 ;
  7. }

Pop出栈

  1. void Pop(Stack S)
  2. {
  3. PtrToNode FirstCell ;
  4. FirstCell = S->Next ;
  5. S->Next = FirstCell->Next ;
  6. free(FirstCell) ;
  7. }

数组实现

  • 潜在危害:需要提前声明栈的大小
  • 实现思路:
    1. 栈指针TopOfStack //并不是指针,只是指示下标
    2. 压栈Stack[TopOfStack] = x TopOfStack++ ;
    3. 出栈,TopOfStack-- ;

栈的声明

  1. struct StackRecord ;
  2. typedef struct StackRecord *Stack ;
  3. int IsEmpty(Stack S) ;
  4. Stack CreateStack(int MaxElements) ;
  5. void DisposeStack(Stack S) ;
  6. void MakeEmpty(Stack S) ;
  7. void Push(ElementType X,Stack S) ;
  8. ElementType Top(Stack S) ;
  9. void Pop(Stack s) ;
  10. define EmptyTOS(-1) ; //空栈标志 加#
  11. define MinStackSize (5) ;
  12. struct Node
  13. {
  14. ElementType *Array ;
  15. int Capacity ;
  16. int TopOfStack ;
  17. }

栈的创建//数组实现

  1. Stack CreateStack(int MaxElements)
  2. {
  3. Stack S ;
  4. if(MaxElements < MinStackSize)
  5. Error("栈过小")
  6. S = malloc(sizeof(struct Node) ;
  7. if(S == NULL)
  8. FatalError("内存不足")
  9. S->Array = malloc(sizeof(struct Node) * MaxElements) ;
  10. if(S->Array = NULL)
  11. FatalError("内存不足") ;
  12. S->Capacity = MaxElements ;
  13. MakeEmpty(S) ;
  14. }
  15. void MakeEmpty(Stack S)
  16. {
  17. S->TopOfStack = EmptyTOS ;
  18. }

释放栈函数

  1. void DisposeStack(Stack S)
  2. {
  3. if(S != NULL)
  4. {
  5. free(S->Array) ;
  6. free(S) ;
  7. }
  8. }

检测空栈函数

  1. void IsEmpty(Stack S)
  2. {
  3. return S->TopOfStack == EmptyTOS ;
  4. }

释放栈函数

  1. void Dispose(Stack S)
  2. {
  3. if(S != NULL)
  4. {
  5. free(S->Array) ;
  6. free(S) ;
  7. }
  8. }

压栈函数

  1. void Push(ElementType X, Stack S)
  2. {
  3. if(IsFull(S))
  4. Error("栈满了") ;
  5. else
  6. S->Array[++S->TopOfStack] = X ;
  7. }

返回栈顶函数

  1. ElementType Top(Stack S)
  2. {
  3. if(!IsEmpty(S))
  4. return S->Array[S->TopOfStack]
  5. Error("空栈")
  6. return 0 ;
  7. }

出栈函数

  1. void Pop(Stack S)
  2. {
  3. if(IsEmpty(S))
  4. Error("空栈") ;
  5. S->TopOfStack-- ;
  6. }

栈的应用

  • 平衡符号

    1. 后缀表达式
    2. 中缀表达式->后缀表达式
    3. 函数调用

队列模型

  • Enqueue入队 在表的末端插入一个元素
  • Dequeue出队 返回或者删除表的开头的元素
  • FIFO先进先出

队列的实现

数组实现

注意问题:数组浪费为题

解决:循环数组

队列的类型声明

  1. struct QueueRecord ;
  2. typedef struct QueueRecord *Queue ;
  3. int IsEmpty(Queue Q) ;
  4. int IsFull(Queue Q) ;
  5. Stack CreateQueue(int MaxElements) ;
  6. void DisposeQueue Q(Queue Q) ;
  7. void MakeEmpty(Queue Q) ;
  8. void Enqueue(ElementType X,Queue Q) ;
  9. ElementType Front(Queue Q) ;
  10. void Dequeue(Queue Q) ;
  11. ElementType FrontAndQueue(Queue Q) ;
  12. #define MinQueueSize(5) ;
  13. Struct QueueRecord
  14. {
  15. int capacity ;
  16. int Front ;
  17. int Rear ;
  18. int Size ;
  19. ElementType *Array ;
  20. }

检测队列是否为空和构造空队列

  1. void IsEmpty(Queue Q)
  2. {
  3. return Q->Size == 0 ;
  4. }
  5. void MakeEmpty(Queue Q)
  6. {
  7. Q->Size = 0 ;
  8. Q->Front = 1 ;
  9. Q->Rear = 0 ;
  10. }

Eequeue入队函数

  1. void Enqueue(ElementType X, Queue Q)
  2. {
  3. if(IsFull(Q)
  4. Error("队列已满")
  5. Q->Size++ ;
  6. Q->Rear = Succ(Q->Rear,Q) ;
  7. Q->Array[Q->Rear] = X ;
  8. }
  9. int Succ(int Value, Queue Q)
  10. {
  11. if(++Value == Q->Capacity)
  12. Value = 0 ;
  13. return Value ;
  14. }

Dequeue出队函数

  1. ElementType Dequeue(Queue Q)
  2. {
  3. ElementType Tmp ;
  4. if(Q->Rear < Q->Front)
  5. Error("队列为空")
  6. Q->Size++ ;
  7. Tmp = Q->Array[Q->Front] ;
  8. Q->Front = Succ(Q->Front,Q) ;
  9. return Tmp ;
  10. }

总结

  • 栈和队列都属于表的一种,只是支持更特殊的操作而已
  • 且用途广泛

栈和队列ADT -数据结构(C语言实现)的更多相关文章

  1. 详细分析栈和队列的数据结构的实现过程(Java 实现)

    目录 栈和队列的数据结构的实现过程(Java 实现) 栈的数据结构的实现 栈的基础知识回顾 栈的常见应用 基于数组的栈的实现 具体代码设计 基于数组的栈简单的时间复杂度分析 关于栈的一个算法应用:括号 ...

  2. 九度OJ 1512 用两个栈实现队列 【数据结构】

    题目地址:http://ac.jobdu.com/problem.php?pid=1512 题目描述: 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 输入: 每 ...

  3. js数据结构之栈、队列(数据结构与拉火车游戏)

    1.js实现队列的数据结构(先进先出) function Queue (array) { if(Object.prototype.toString.call(array)!="[object ...

  4. 三元组ADT (数据结构C语言版) C++实现

    很久没用C语言,都忘了C语言中没有引用参数,下面的代码中用到了C语言没有的引用参数. 首先是一些表示状态的全局变量 common.h #define TRUE 1 #define FALSE 0 #d ...

  5. 数据结构之栈和队列及其Java实现

    栈和队列是数据结构中非常常见和基础的线性表,在某些场合栈和队列使用很多,因此本篇主要介绍栈和队列,并用Java实现基本的栈和队列,同时用栈和队列相互实现. 栈:栈是一种基于“后进先出”策略的线性表.在 ...

  6. 《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

    表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了声明. 本章学习重点: 理解抽象数据类 ...

  7. C语言数据结构——第三章 栈和队列

    三.栈和队列 栈和队列是两种重要的线性结构.从数据结构的角度来看,栈和队列也是线性表,它的特殊性在于栈和队列的基本操作是线性表操作的子集,它们的操作相对于线性表来说是受到限制的,因此,可以称其为限定性 ...

  8. 数据结构(c语言第2版)-----了解链表,栈,队列,串

    关于链表我觉得这都是最基本的东西,但是不常见,在实际的应用中很少的使用,了解它会用就OK,不需要研究的那么深,除非做那种内存压缩,存储方面工作. C语言中动态申请空间 malloc() q=(dlin ...

  9. 深入浅出数据结构C语言版(7)——特殊的表:队列与栈

    从深入浅出数据结构(4)到(6),我们分别讨论了什么是表.什么是链表.为什么用链表以及如何用数组模拟链表(游标数组),而现在,我们要进入到对线性表(特意加了"线性"二字是因为存在多 ...

随机推荐

  1. 100个常用的linux命令(转)

    来源:JavaRanger – javaranger.com   http://www.javaranger.com/archives/907 1,echo “aa” > test.txt 和 ...

  2. Kubernetes组件与架构

    转载请标明出处: 文章首发于>https://www.fangzhipeng.com/kubernetes/2018/09/30/k8s-basic1/ 本文出自方志朋的博客 Kubernete ...

  3. position定位笔记

    position定位 position一共有四个可选属性:static/relative/absolute/fixed 代码: <style type="text/css"& ...

  4. mysql update 子查询锁表问题

    mysql在Update带有子查询的时候,子查询的表会锁住,导致该表无法使用.比如 update A set comments = (select count(1) from B where id = ...

  5. java web中对json的使用

    一.在Java Web的开发过程中,如果希望调用Java对象转化成JSON对象等操作.则需要引入以下jar包,不然运行时则报错. 1.commons-beanutils.jar 2.commons-c ...

  6. oc中文首字母排序

    oc中文首字母排序 NSArray *arr2=@[@"小雨",@"安安",@"小风",@"荣荣",@"张涛& ...

  7. 几行代码实现iOS摇一摇功能

    实现这个功能很简单,我们直接看代码 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event{ NSLog(@&quo ...

  8. ubnutu 安装protocol buffer

    工作中需要使用protocol buffer,需要编译出protocol buffer的动态链接库,然后在别的makefile中链接它, 我的环境是ubnutu16.04,64bit,使用的proto ...

  9. 开源框架:DBUtils使用详解

    一.先熟悉DBUtils的API: 简介:DbUtils是一个为简化JDBC操作的小类库. (一)整个dbutils总共才3个包: 1.包org.apache.commons.dbutils    接 ...

  10. 解决IDEA右键 new 没有新建class/Interface等等选项

    1.File->Project Structure 2.选择Modules-->右边Sources中选择所需目录 然后点击 Sources-->Apply-->OK 3.再在左 ...