勤于总结,持续输出!

1.栈

1.1栈的定义

栈(stack)是限定在表尾进行插入和删除的操作的线性表

我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不包含任何数据元素的栈称为空栈。栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。

栈的插入操作,叫做进栈,也称压栈、入栈。

栈的删除操作,叫做出栈,也称弹栈。

1.2栈的顺序存储结构及实现

既然栈是线性表的特例,那么栈的顺序存储其实也是线性表顺序存储的简化。

用数组实现,下标为0的一端作为栈底比较好,因为首元素都存在栈底。

栈的结构定义:

定义一个top变量来指示栈顶元素在数组中的位置,若存储栈的长度为SackSize,则栈顶位置top必须小于SackSize。当栈存在一个元素时,top等于0,因此通常把空栈的判定条件为top=-1。

typedef int SElemType;
typedef struct
{
SElemType data[MAXSIZE];
int top; /*用于栈顶指针*/
} SqStack;

1.3栈的顺序存储结构——进栈操作

代码实现:

#define MAXSIZE 5
#define OK 1
#define ERROR 0 /*插入元素e为新的栈顶元素*/
Status Push(SqStack *S, SElemType e)
{
if (S->top == MAXSIZE - 1) /*栈满*/
{
return ERROR;
}
S->top++;
S->data[S->top] = e;
return OK;
}

测试代码:

int main()
{
SqStack stack = { {1,2},1 }; /*初始化栈内有两个元素,top=1*/
Push(&stack, 3);
}

运行结果:

1.4栈的顺序存储结构——出栈操作

代码实现:

#define MAXSIZE 5
#define OK 1
#define ERROR 0 /*若栈不为空,则删除S的栈顶元素,用e返回其值*/
Status Pop(SqStack *S, SElemType *E)
{
if (S->top == -1)
{
return ERROR;
}
*E = S->data[S->top];
S->data[S->top] = NULL;
S->top--;
return OK;
}

测试代码:

int main()
{
SElemType e;
SqStack stack = { {1,2},1 }; /*初始化栈内有两个元素,top=1*/
Push(&stack, 3);
Pop(&stack, &e);
}

运行结果:

验证了后进先出的结构。

1.5栈的链式存储结构及实现

栈的链式存储结构,简称为栈链。由于单链表有头指针,而栈顶指针也是必须的,那么便可以让它俩合二为一。以为就是说栈顶放在单链表的头部。

对于链栈来说,基本不存在栈满的情况,除非内存已经没有可以使用的空间。但是对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是top=NULL。

栈链的结构代码如下:

typedef int SElemType;
typedef struct StackNode
{
SElemType data;
struct StackNode *next;
} StackNode;
typedef struct StackNode *LinkStackPtr; typedef struct LinkStatck
{
LinkStackPtr top;
int count;
}LinkStatck;

1.6栈的链式存储结构——进栈操作

代码实现:

#define OK 1
#define ERROR 0
typedef int Status;
typedef int SElemType; /*插入元素e为新的栈顶元素*/
Status Push(LinkStatck *S, SElemType e)
{
LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode));
s->data = e;
s->next = S->top;
S->top = s; /*将新的节点s赋值给栈顶指针*/
S->count++;
return OK;
}

测试代码:

int main()
{
LinkStatck stack = { NULL ,0}; /*初始化一个空链栈*/
Push(&stack, 1);
Push(&stack, 2);
Push(&stack, 3);
}

运行结果:

动画模拟:

1.7栈的链式存储结构——出栈操作

代码实现:

#define OK 1
#define ERROR 0
typedef int Status;
typedef int SElemType; /*若栈不为空,则删除S的栈顶元素,用e返回其值*/
Status Pop(LinkStatck *S, SElemType *e)
{
LinkStackPtr p;
if (S->count == 0)
{
return ERROR;
}
*e = S->top->data;
p = S->top; /*将栈顶节点赋值给p*/
S->top = S->top->next; /*使栈顶指针下移一位,指向后一节点*/
free(p); /*释放节点p*/
S->count--;
return OK;
}

测试代码:

int main()
{
LinkStatck stack = { NULL ,0}; /*初始化一个空链栈*/
Push(&stack, 1);
Push(&stack, 2);
Push(&stack, 3);
SElemType e;
Pop(&stack, &e);
Pop(&stack, &e);
Pop(&stack, &e);
}

运行结果:

动画模拟:

2.队列

2.1队列的定义

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。

队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。

2.2队列的顺序存储结构

我们假设一个队列有n个元素,则顺序存储的队列需建立一个大于n的数组。

现在进行入队操作,就是在队尾插入一个元素,不需要移动任何元素,因此时间复杂度是O[1]。

出队操作是在队头,那么队列中所有的元素都要向前移动一个位置,确保下标为0的位置不为空,时间复杂度是O[n],这是个问题。

如果不限定出队操作时所有的元素都要向前移动,也就是说队头不一定必须在下标为0 的位置,出队的性能就会大大增加。

但是这样又会出现另一个问题——假溢出,就是假设队列前面的位置是空着的,但是从队尾入队已经满了。

循环队列可以解决这一个问题,后面满了,就从头再开始,也就是头尾相接的循环,这种头尾相接的顺序存储结构称为循环队列。

但是循环队列还是会面临着数组溢出的问题。

2.3队列的链式存储结构及实现

队列的链式存储结构,其实就是线性表的单链表,只不过它能尾进头出而已,简称链队列。

队头指针指向链队列的头节点,而队尾指针指向终端节点:

空队列时都指向头节点:

链队列的结构如下:

typedef int QElemType;
typedef struct QNode /*结点结构*/
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr; typedef struct /*队列的链表结构*/
{
QueuePtr front, rear; /*队头、队尾指针*/
} LinkQueue;

2.4队列的链式存储结构——入队操作

入队操作,在队尾插入新元素。

代码实现:

#define OK 1
#define ERROR 0 typedef int Status;
/*插入元素e为Q的新的队尾元素*/
Status EnQueue(LinkQueue *Q, QElemType e)
{
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
s->data = e;
s->next = NULL; Q->rear->next = s; /*把拥有元素e新节点s赋值给原队尾结点的后继*/
Q->rear = s; /*把s设置为队尾结点,rear指向s*/ return OK;
}

测试代码:

int main()
{
/*头结点*/
QueuePtr head = (QueuePtr)malloc(sizeof(QNode));
head->data = 0;
head->next = NULL; LinkQueue q = { head ,head }; //空队列,队头、队尾指针都指向头结点 EnQueue(&q, 1);
EnQueue(&q, 2);
}

运行结果:

动画模拟:

2.4队列的链式存储结构——出队操作

代码实现:

#define OK 1
#define ERROR 0 typedef int Status;
/*若队列不为空,删除Q的队头元素,用e返回其值*/
Status DeQueue(LinkQueue *Q, QElemType *e)
{
QueuePtr p;
if (Q->front == Q->rear)
{
return ERROR;
}
p = Q->front->next; /*将欲删除的队头节点暂存给p*/
*e = p->data;
Q->front->next = p->next; /*将原队头结点后继赋值给头结点后继*/ if (Q->rear == p) /*若队头是队尾,则删除后将rear指向头结点*/
{
Q->rear = Q->front;
} free(p);
return OK;
}

测试代码:

int main()
{
/*头结点*/
QueuePtr head = (QueuePtr)malloc(sizeof(QNode));
head->data = 0;
head->next = NULL; LinkQueue q = { head ,head }; EnQueue(&q, 1);
EnQueue(&q, 2);
QElemType e;
DeQueue(&q, &e);
}

运行结果:

动画模拟:

参考:《大话数据结构》


本文为博主学习感悟总结,水平有限,如果不当,欢迎指正。

如果您认为还不错,不妨点击一下下方的【推荐】按钮,谢谢支持。

转载与引用请注明出处。

【图解数据结构】 栈&队列的更多相关文章

  1. 数据结构 栈&队列

    2-4 依次在初始为空的队列中插入元素a,b,c,d以后,紧接着做了两次删除操作,此时的队头元素是( ) 删除,移动头指针: 增加,移动尾指针: 删除a,b ,队头c 2-3 在一个链队列中,fron ...

  2. 数据结构之队列and栈总结分析

    一.前言: 数据结构中队列和栈也是常见的两个数据结构,队列和栈在实际使用场景上也是相辅相成的,下面简单总结一下,如有不对之处,多多指点交流,谢谢. 二.队列简介 队列顾名思义就是排队的意思,根据我们的 ...

  3. 数据结构和算法(Golang实现)(14)常见数据结构-栈和队列

    栈和队列 一.栈 Stack 和队列 Queue 我们日常生活中,都需要将物品排列,或者安排事情的先后顺序.更通俗地讲,我们买东西时,人太多的情况下,我们要排队,排队也有先后顺序,有些人早了点来,排完 ...

  4. java 集合 Connection 栈 队列 及一些常用

    集合家族图 ---|Collection: 单列集合 ---|List: 有存储顺序 , 可重复 ---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实 ...

  5. Java 容器之 Connection栈队列及一些常用

    集合家族图 ---|Collection: 单列集合 ---|List: 有存储顺序 , 可重复 ---|ArrayList: 数组实现 , 查找快 , 增删慢 ---|LinkedList: 链表实 ...

  6. C++ 泛型 编写的 数据结构 栈

    平时编程里经常需要用到数据结构,比如  栈和队列 等,  为了避免每次用到都需要重新编写的麻烦现将  C++ 编写的 数据结构   栈   记录下来,以备后用. 将 数据结构  栈   用头文件的形式 ...

  7. java面向对象的栈 队列 优先级队列的比较

    栈 队列 有序队列数据结构的生命周期比那些数据库类型的结构(比如链表,树)要短得多.在程序操作执行期间他们才被创建,通常用他们去执行某项特殊的任务:当完成任务之后,他们就会被销毁.这三个数据结构还有一 ...

  8. JavaScript数据结构——栈的实现与应用

    在计算机编程中,栈是一种很常见的数据结构,它遵从后进先出(LIFO——Last In First Out)原则,新添加或待删除的元素保存在栈的同一端,称作栈顶,另一端称作栈底.在栈中,新元素总是靠近栈 ...

  9. javascript数据结构之队列

    首先什么是队列? 排队买东西就是生活中队列的实际例子,在队伍中大家必须按照顺序来,不能插队,新来的人只能排在队伍的最后面.新加入的人相当于队列的后端加入的元素,队伍最前面买完东西的人离开队伍相当于是队 ...

  10. 栈 & 队列

    栈 先进者后出,后进者先出,LIFO,典型的"栈"结构 从栈的操作特性上来看,栈是一种"操作受限"的线性表,只允许在一段插入和删除数据. 在功能上来说,数组和链 ...

随机推荐

  1. Matlab绘图基础——axis设置坐标轴取值范围

    peaks; axis tight  %Set the axis limits to equal the range of the data  axis square axis 'auto x'  % ...

  2. Java 小记 — RabbitMQ 的实践与思考

    前言 本篇随笔将汇总一些我对消息队列 RabbitMQ 的认识,顺便谈谈其在高并发和秒杀系统中的具体应用. 1. 预备示例 想了下,还是先抛出一个简单示例,随后再根据其具体应用场景进行扩展,我觉得这样 ...

  3. ansible之一:安装与配置

    ansible特点: 1.不需要安装客户端,通过sshd去通信 2.基于模块工作,模块可以由任何语言开发 3.不仅支持命令行试用模块,也支持yaml格式得playbook 4.支持sudo 5.有提供 ...

  4. javaAPI中的常用 类 以及接口

    java.lang包中的常用类以及接口 类 1. Integer :Integer 类在对象中包装了一个基本类型 int 的值.Integer 类型的对象包含一个 int 类型的字段. 2. Math ...

  5. java基础笔记(2)----流程控制

    java流程控制结构包括顺序结构,分支结构,循环结构. 顺序结构: 程序从上到下依次执行,中间没有任何判断和跳转. 代码如下: package com.lvsling.test; public cla ...

  6. 真是没想到,ikvm.net居然停止开发了。

    看样子作者对.net已经失去了信心 http://weblog.ikvm.net/CommentView.aspx?guid=33ea525f-a291-418a-bd6a-abdf22d0662b# ...

  7. alpha-咸鱼冲刺day1-紫仪

    总汇链接 一,合照 emmmmm.自然是没有的. 二,项目燃尽图 三,项目进展   登陆界面随意写了一下.(明天用来做测试的) 把学姐给我的模板改成了自家的个人主页界面,侧边栏啥的都弄出来了(快撒花花 ...

  8. 201621123050 《Java程序设计》第14周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结与数据库相关内容. 2. 使用数据库技术改造你的系统 2.1 简述如何使用数据库技术改造你的系统.要建立什么表?截图你的表设计. 答 ...

  9. 代码中输入数字自动筛选出最大值,使用array,for loop and if (21.9.2017)

    # include <stdio.h> # define N main(){ int a, b; ,,,,,,,,,,,,,,,,}; //array中输入需要排序的数字 ]; ; a & ...

  10. 位图(BitMap)

    位图 引入:2.给40亿个不重复的无符号整数,没排过序.给一个无符号整数,如何快速判断一个数是否在这40亿个数中. [腾讯] 思路:如果内存够的话,40亿个整型使用位图存储需要500M左右的空间. 分 ...