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. JVM垃圾回收(下)

    接着上一篇,介绍完了 JVM 中识别需要回收的垃圾对象之后,这一篇我们来说说 JVM 是如何进行垃圾回收. 首先要在这里介绍一下80/20 法则: 约仅有20%的变因操纵着80%的局面.也就是说:所有 ...

  2. 基于vue组件,发布npm包

    亲测好用,如出错,请留言 1.项目初始化 使用vue脚手架创建,但vuecli太重,我们使用简单的工程脚手架进行处理,输入命令 vue init webpack-simple my-project n ...

  3. shark恒破解笔记1-壳内寻找注册码

    记录学习shark恒大教程的学习记录 壳内寻找注册码 OD打开 明显有壳 F9先运行程序 2.Ctrl+G输入401000到解码段,如果出现db ** 说明已经解码过,脱离了程序本身的壳 鼠标右键-& ...

  4. PBO项目的组织

    前言: 最近发现PMI的英文官网已经公布了第五版PMBOK的初稿,针对第四版而言的确有了不少变动.了解这些变动,对理解项目管理知识的整理和发展,以及掌握PMP考试的变化方向都是很重要的.当然,变动尤其 ...

  5. ubuntu16.04 gcc升级到7.3

    下载gcc- wget https://mirrors.ustc.edu.cn/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.gz 运行 download_prerequisites ...

  6. vue css 深度选择器

    在我们想穿透的选择器前边添加 >>> 或者 /deep/ 或者 ::v-deep. 官方地址:https://vue-loader.vuejs.org/guide/scoped-cs ...

  7. echarts折线图动态改变数据时的一个bug

    echarts折线图中当增加dataZoom,修改start大于0的时候,会出现折线混乱,变成竖直的线,绘制有问题. 解决方法,在dataZoom中增加filterMode: 'empty' http ...

  8. POI读入Excel用String读取数值类型失真问题(精度丢失)

    问题:POI读取Excel数值单元格时,读取的小数数值与真实值不一致 话不多说,直接上代码! public static String getRealStringValue(Cell cell) { ...

  9. python中生成器与迭代器

    可迭代对象:一个实现了iter方法的对象是可迭代的 迭代器:一个实现了iter方法和next方法的对象就是迭代器 生成器都是Iterator对象,但list.dict.str虽然是Iterable(可 ...

  10. Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials

    原文链接:Sentinel Getting Started And Integration of Spring Cloud Alibaba Tutorials Sentinel Getting Sta ...