1.堆栈

堆栈(Stack):具有一定操作约束的线性表(只在一端(栈顶,Top)做插入、删除)

  • 先进后出特性

1.1堆栈的抽象数据类型描述

类型名称: 堆栈(Stack)

数据对象集:一个有0个或多个元素的有穷线性表。

操作集:长度为MaxSize的堆栈S  Stack,堆栈元素item  ElementType

1、Stack CreateStack( int MaxSize ): 生成空堆栈,其最大长度为MaxSize;

2、int IsFull( Stack S, int MaxSize ):判断堆栈S是否已满;

3、void Push( Stack S, ElementType item ):将元素item压入堆栈;

4、int IsEmpty ( Stack S ):判断堆栈S是否为空;

5、ElementType Pop( Stack S ):删除并返回栈顶元素;

Push 和 Pop 可以穿插交替进行;

按照操作系列

(1)Push(S,A), Push(S,B),Push((S,C),Pop(S),Pop(S),Pop(S)

堆栈输出是?

CBA

(2) 而Push(S,A), Pop(S),Push(S,B),Push((S,C),Pop(S),Pop(S)

堆栈输出是?

ACB

栈分为顺序栈和链式栈。

1.2顺序栈

栈的顺序存储结构通常由一个一维数组和一个记录栈顶元素位置的变量组成。

1.顺序栈定义

#define MaxSize <储存数据元素的最大个数>
typedef struct SNode *Stack;
struct SNode {
ElementType Data[MaxSize];
int Top;
};

2.入栈

void Push( Stack PtrS, ElementType item ) {
if ( PtrS->Top == MaxSize-1 ) {
printf("堆栈满");
return;
} else {
PtrS->Data[++(PtrS->Top)] = item;
return;
}
}

3.出栈

ElementType Pop( Stack PtrS ) {
if ( PtrS->Top == -1 ) {
printf("堆栈空");
return ERROR; /* ERROR是ElementType的特殊值,标志错误 */
} else
return ( PtrS->Data[(PtrS->Top)--] );
}

1.3链式栈

栈的链式存储结构实际上就是一个单链表,叫做链栈。插入和删除操作只能在链栈的栈顶进行。

1.链式栈定义

typedef struct SNode *Stack;
struct SNode {
ElementType Data;
struct SNode *Next;
} ;

2.堆栈初始化(建立空栈)

Stack CreateStack() {
/* 构建一个堆栈的头结点,返回指针 */
Stack S;
S =(Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}

3.判断堆栈是否为空

int IsEmpty(Stack S)
{
/*判断堆栈S是否为空,若为空函数返回整数1,否则返回0 */
return ( S->Next == NULL );
}

这里的S并不是头节点,而是指向头节点

4.入栈

void Push( ElementType item, Stack S) {
/* 将元素item压入堆栈S */
struct SNode *TmpCell;
TmpCell=(struct SNode *)malloc(sizeof(struct SNode));
TmpCell->Element = item;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}

5.出栈

ElementType Pop(Stack S) {
/* 删除并返回堆栈S的栈顶元素 */
struct SNode *FirstCell;
ElementType TopElem;
if( IsEmpty( S ) ) {
printf(“堆栈空”);
return NULL;
} else {
FirstCell = S->Next;
S->Next = FirstCell->Next;
TopElem = FirstCell ->Element;
free(FirstCell);
return TopElem;
}
}

2.队列

队列(Queue):具有一定操作约束的线性表

  • 插入和删除操作:只能在一端插入,而在另一端删除。
  • FIFO:先进先出

2.1队列的抽象数据类型描述

类型名称:队列(Queue)

数据对象集:一个有0个或多个元素的有穷线性表。

操作集:长度为MaxSize的队列Q  Queue,队列元素item  ElementType

1、Queue CreatQueue( int MaxSize ):生成长度为MaxSize的空队列;

2、int IsFullQ( Queue Q, int MaxSize ):判断队列Q是否已满;

3、void AddQ( Queue Q, ElementType item ): 将数据元素item插入队列Q中;

4、int IsEmptyQ( Queue Q ): 判断队列Q是否为空;

5、ElementType DeleteQ( Queue Q ):将队头数据元素从队列中删除并返回。

2.2顺序队列

队列的顺序存储结构通常由一个一维数组和一个记录队列头元素位置的变量front以及一个记录队列尾元素位置的变量rear组成。

1.顺序队列结构体定义

#define MaxSize <储存数据元素的最大个数>
struct QNode {
ElementType Data[ MaxSize ];
int rear;
int front;
};
typedef struct QNode *Queue;

顺序队列的一个劣势就是,随着数据的入队列和出队列,front和rear指针会一直向右移动,最终可能无法再添加新的元素,但是这个时候数组其实还有很多的空间,为了让队列继续可用,就需要数据搬移。

而为了避免数据搬移,就会把顺序存储结构的队列设计成循环队列

循环队列的本质就是在入队列的时候,rear指针会回到数组的前面去。

你也可以把它的逻辑图画成这样

队列空:

front==rear

队列满:

(rear+1)%maxsize == front

2.入队列

void AddQ( Queue PtrQ, ElementType item) {
if ( (PtrQ->rear+1) % MaxSize == PtrQ->front ) {
printf("队列满");
return;
}
PtrQ->Data[PtrQ->rear] = item;
PtrQ->rear = (PtrQ->rear+1)% MaxSize;
}

3.出队列

ElementType DeleteQ ( Queue PtrQ ) {
if ( PtrQ->front == PtrQ->rear ) {
printf("队列空");
return ERROR;
} else {
ElementType x = PtrQ->Data[PtrQ->front];
PtrQ->front = (PtrQ->front+1)% MaxSize;
return x;
}
}

2.3链式队列

队列的链式存储结构也可以用一个单链表实现。插入和删除操作分别在链表的两头进行。

1.链式队列结构体定义

struct Node {
ElementType Data;
struct Node *Next;
};
struct QNode { /* 链队列结构 */
struct Node *rear; /* 指向队尾结点 */
struct Node *front; /* 指向队头结点 */
};
typedef struct QNode *Queue;
Queue PtrQ;

2.出队列

ElementType DeleteQ ( Queue PtrQ ) {
struct Node *FrontCell;
ElementType FrontElem;
if ( PtrQ->front == NULL) {
printf("队列空");
return ERROR;
}
FrontCell = PtrQ->front;
if ( PtrQ->front == PtrQ->rear) /* 若队列只有一个元素 */
PtrQ->front = PtrQ->rear = NULL; /* 删除后队列置为空 */
else
PtrQ->front = PtrQ->front->Next;
FrontElem = FrontCell->Data;
free( FrontCell ); /* 释放被删除结点空间 */
return FrontElem;
}

3.入队列

void AddQ( Queue Q, ElementType x)
{
Node *newnode =(Node*)malloc(sizeof(Node));
newnode->Data = x;
newnode->Next = NULL;
if ( PtrQ->front == NULL) {
//空队列
Q->front = Q ->rear = newnode;
} else{
Q->rear->Next = newnode;
Q->rear = newnode;
}
}

【algo&ds】3.栈和队列的更多相关文章

  1. DS博客作业03——栈和队列

    1.本周学习总结 谈谈你对栈和队列结构的认识及学习体会. 栈和队列的本质就是线性表.所以,相应的栈跟队列都有两种存储结构:顺序存储结构.链式存储结构. 栈的特点是后进先出,根据栈时进时出的规则,出栈的 ...

  2. DS博客作业03—栈和队列

    1.本周学习总结 本周学习了栈和队列两种数据结构,分别对应后进先出,先进先出两种数据操作 学会栈的特殊类型-共享栈,队列的特殊类型-循环队列的一系列操作 学会熟练使用栈和队列的STL容器,使代码简洁 ...

  3. 学习javascript数据结构(一)——栈和队列

    前言 只要你不计较得失,人生还有什么不能想法子克服的. 原文地址:学习javascript数据结构(一)--栈和队列 博主博客地址:Damonare的个人博客 几乎所有的编程语言都原生支持数组类型,因 ...

  4. [ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 1338+2442+1442)

    再次面对像栈和队列这样的相当基础的数据结构的学习,应该从多个方面,多维度去学习. 首先,这两个数据结构都是比较常用的,在标准库中都有对应的结构能够直接使用,所以第一个阶段应该是先学习直接来使用,下一个 ...

  5. 剑指Offer面试题:6.用两个栈实现队列

    一.题目:用两个栈实现队列 题目:用两个栈实现一个队列.队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的功能. 原文是使用 ...

  6. C实现栈和队列

    这两天再学习了数据结构的栈和队列,思想很简单,可能是学习PHP那会没有直接使用栈和队列,写的太少,所以用具体代码实现的时候出现了各种错误,感觉还是C语言功底不行.栈和队列不论在面试中还是笔试中都很重要 ...

  7. JavaScript数组模拟栈和队列

    *栈和队列:js中没有真正的栈和队列的类型              一切都是用数组对象模拟的 栈:只能从一端进出的数组,另一端封闭       FILO   何时使用:今后只要仅希望数组只能从一端进 ...

  8. 用JS描述的数据结构及算法表示——栈和队列(基础版)

    前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里 ...

  9. JavaScript中的算法之美——栈、队列、表

    序 最近花了比较多的时间来学习前端的知识,在这个期间也看到了很多的优秀的文章,其中Aaron可能在这个算法方面算是我的启蒙,在此衷心感谢Aaron的付出和奉献,同时自己也会坚定的走前人这种无私奉献的分 ...

  10. Java数据结构和算法之栈与队列

    二.栈与队列 1.栈的定义 栈(Stack)是限制仅在表的一端进行插入和删除运算的线性表. (1)通常称插入.删除的这一端为栈顶(Top),另一端称为栈底(Bottom). (2)当表中没有元素时称为 ...

随机推荐

  1. Java8新特性之Lambda

    为什么要Lambda Java8应该是目前最大的一次更新了,更新后我们迎来了很多新特性,其中便包括Lambda表达式,函数式编程的思想正式进入Java,让我们看一个经典案例. 例1 按照两个人的年龄排 ...

  2. 一个基于C++11的单例模板类

    #ifndef _SINGLETON_H_#define _SINGLETON_H_ template<typename T>class Singleton : public Uncopy ...

  3. lnmp安装mysql

    lnmp安装mysql 下载lnmp wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz 解压 tar ‐xf lnmp1..tar.gz 安装数据库 ./i ...

  4. Canonical 开源 MicroK8 | 云原生生态周报 Vol. 25

    业界要闻 1.Canonical 开源 MicroK8 面向工作站和边缘/物联网的零运维 Kubernetes!MicroK8 是 Canonical 提供的一款功能强大的企业级 Kubernetes ...

  5. navicat cannot load oci dll||oracle 改字符集为GBK后 navicat 连不上||Ora-28547 ora net错误

    此段适用于 解决 navicat cannot load oci dll 环境 Navicat Premium  和 oracle 原因,navicat 32 和64 都只支持 32位的oci.dll ...

  6. 150行代码搭建异步非阻塞Web框架

    最近看Tornado源码给了我不少启发,心血来潮决定自己试着只用python标准库来实现一个异步非阻塞web框架.花了点时间感觉还可以,一百多行的代码已经可以撑起一个极简框架了. 一.准备工作 需要的 ...

  7. 解压zip文件

    /// <summary> /// 执行压缩命令结果 /// </summary> public enum CompressResults { Success, SourceO ...

  8. 如何在Spring Boot项目中巧妙利用策略模式干掉if else!

    直入主题 我们都知道,设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路.它不是语法规定,而是一套用来提高代码可复用性.可维护性.可读性.稳健性以及安全性 ...

  9. git从远程仓库拉取内容或向远程仓库上传内容

    一.将本地文件上传到远程仓库步骤 git init git add . git commit -m "初始框架" git remote add origin https://git ...

  10. 一:VSCode引入jupyter

    1:安装 2:示例代码 #%% import matplotlib.pyplot as plt import matplotlib as mpl import numpy as np x , , ) ...