数据结构与算法分析:栈与队列

以下是对数据结构中的栈和队列的一些总结:

一、栈

栈(Stack)是一种特殊的线性表,有后进先出(Last In First Out, LIFO)的性质,且只能从线性表的一段进行插入和删除元素等操作。

栈的常用操作有:进栈、出栈、取栈顶、将栈置空、判断栈是否为空、判断栈是否已满等等。

由于栈也属于线性表,因此线性表的存储结构对栈也适用,因此,使用数组或者单向链表均可以实现栈。这两种存储结构的不同,因此实现栈的方式也有不同,形成的栈的性质也有所不同。一个常见的区别是,在顺序栈中有“上溢”和“下溢”的概念,即当栈已经满了还存数据称为“上溢”,栈已经空了还执行取数据操作成为“下溢”。而链式栈则没有“上溢”的限制,因为可以在可操作的一头自由增加新的结点而不会溢出。

1.线性栈

顺序栈,需要设计一个规定大小SIZE的数组来存储整个栈,设下标为0的元素就是栈底元素,用top变量来指示栈顶元素的下表,因为数组的大小为SIZE,因此0 <= top < SIZE。当top = 0时表示该栈只有一个元素;当top = SIZE - 1时表示栈满;同理,可以令top = -1表示当前的栈为空栈。

2.链式栈

线性栈的缺点明显,因其大小固定,因此若要入栈的元素数目无法估计则容易出现栈溢出的情况,此时应该考虑使用链式存储结构,即链式栈。需要注意的是,链式栈不需要在头部附加头结点,因为栈都是在头部进行操作的。

二、队列

队列(Queue)也是一种特殊的线性表,它的限制与栈不同,在表的两头都有限制,插入只能在表的一端进行,只进不出;而删除只能在表的另一端进行,只出不进。允许插入数据的一端称为队头 (front),允许删除的一端称为队尾(rear)。队列的性质与栈相反,是先进先出(First In First Out, FIFO)的。

与栈差别不大,队列的常用操作主要有:进队、出队、取对头数据、将队列置空、判断队列是否为空、判断队列是否已满等等。

与栈相似,队列也有顺序存储和链式存储两种存储结构,分别称为“顺序队列”和“链队”。

1.顺序队列

建立顺序队列结构必须为其静态分配或动态申请一片连续的存储空间,并设置两个指针进行管理。一个是队头指针front,它指向队头元素;另一个是队尾指针rear,它指向下一个入队元素的存储位置。

当front=rear时,队列中没有任何元素,称为空队列。每次在队尾插入一个元素是,rear增1;每次从队头删除一个元素时,front增1。随着插入和删除操作的进行,队列元素的个数不断变化,队列所占的存储空间也在为队列结构所分配的连续空间中移动。一个操作的例子如下图所示:

顺序队列中的可能出现“下溢”、“真上溢”或“假上溢”等现象,以下一一进行解释:

“下溢”现象:当队列为空时,做出队运算产生的溢出现象。“下溢”是正常现象,常用作程序控制转移的条件。

“真上溢”现象:当队列满时,做进栈运算产生空间溢出的现象。“真上溢”是一种出错状态,应设法避免。

而至于“假上溢”,回到上面举的例子,会发现到了D步骤,当rear增加到指向分配的连续空间之外时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元。这种情况被称为“假上溢”现象。

使队列空间能重复使用,往往对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。

为了克服这种现象造成的空间浪费,可以对队列的使用方法稍加改进:无论插入或删除,一旦rear指针增1或front指针增1时超出了所分配的队列空间,就让它指向这片连续空间的起始位置,这就好比是把向量空间头尾相接,形成一个闭环,此时的队列变成了一个循环队列。

循环队列解决了“假上溢”的问题,但带来一个新的问题。上面提到,在循环队列中,当队列为空时,有front=rear,而当所有队列空间全占满时,同样有front=rear。因此还需要对队列做一些调整才能区别这两种情况。

区别这两种情况的方法有多种,可以用一个计数器记录队列中的元素的总数,这样就可以随时知道队列的长度了,只要队列中的元素个数等于向量空间的长度,就是队满。另一种方法是规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时front=rear,而队列判满的条件时front=(rear+1)%MaxSize。

2.链式队列

链式队列与线性表的单链表相似,不同的是链式队列只允许从头部进行删除、尾部进行插入。需要为链式队列创建一个头结点包括两个指针,指向队头的指针front与指向队尾的指针rear。当两个指针相等时队列为空。

参考资料:

《算法导论》 第三版 (美)科曼(Cormen,T.H.) 等著,殷建平 等译

http://blog.csdn.net/ns_code

http://baike.baidu.com/link?url=9PVFeYIx1ZsbyihHAI5OWrJs2xdOs5eH0I3oZyCwkNG16XnigPbUozfYkRmic_66P8cgu8nEhgGUfJxunhsRFMQsfsVg3nXJs3ceOqFJiAi

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-16 23:59:14

数据结构与算法分析:栈与队列的相关文章

数据结构与算法--栈、队列(队列)

Hello,everybody.我们又见面了.今天我们来学习一下队列这个数据结构,let's Go,开始我们的征程吧. 首先,举两个生活中的常见例子.相信大家,在用电脑工作娱乐时,都会碰到这样的现象.当我们点击程序或进行其他操作时,电脑处于死机状态.正当我们准备Reset时,它突然像打了鸡血似的,突然把刚才我们的操作,按顺序执行了一遍.之所以会出现这个现象,是因为操作系统的多个程序,需要通过一个管道输出,而按先后顺序排队造成的. 还有有个例子,在我们打客服热线时,有时会出现等待的现象.当其他客户

4、蛤蟆的数据结构笔记之四栈和队列定义

4.蛤蟆的数据结构笔记之四栈和队列定义 本篇名言:"人生应该如蜡烛一样,从顶燃到底,一直都是光明的." 今天学习栈和队列了.从第二篇学习时候我们知道,其实也是线性表的一种. 我们先来看下定义. 欢迎转载,转载请标明出处: 1.  栈 栈(stack)又名堆栈,它是一种运算受限的线性表.其限制是仅允许在表的一端进行插入和删除运算.这一端被称为栈顶,相对地,把另一端称为栈底.向一个栈插入新元素又称作进栈.入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素:从一个栈删除元素又称

数据结构与算法分析-栈

数据结构与算法分析-栈(单链表实现) //by xiabodan #include <stdio.h> #include <stdlib.h> typedef int elementtype; typedef struct node *stack; typedef struct node *position; struct node { elementtype data; position next; }; int isempty(stack S); void delete_sta

SDUT 2449 数据结构实验之栈与队列十:走迷宫

数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. Input 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1

SDUT-3335_数据结构实验之栈与队列八:栈的基本操作

数据结构实验之栈与队列八:栈的基本操作 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 堆栈是一种基本的数据结构.堆栈具有两种基本操作方式,push 和 pop.push一个值会将其压入栈顶,而 pop 则会将栈顶的值弹出.现在我们就来验证一下堆栈的使用. Input 首先输入整数t(1 <= t <= 10),代表测试的组数,以后是 t 组输入. 对于每组测试数据,第一行输入两个正整数 m(1 <= m &

SDUT-2088_数据结构实验之栈与队列十一:refresh的停车场

数据结构实验之栈与队列十一:refresh的停车场 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description refresh最近发了一笔横财,开了一家停车场.由于土地有限,停车场内停车数量有限,但是要求进停车场的车辆过多.当停车场满时,要进入的车辆会进入便道等待,最先进入便道的车辆会优先 进入停车场,而且停车场的结构要求只出去的车辆必须是停车场中最后进去的车辆.现告诉你停车场容量N以及命令数M,以及一些命令(Add num 表

SDUT-2449_数据结构实验之栈与队列十:走迷宫

数据结构实验之栈与队列十:走迷宫 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 一个由n * m 个格子组成的迷宫,起点是(1, 1), 终点是(n, m),每次可以向上下左右四个方向任意走一步,并且有些格子是不能走动,求从起点到终点经过每个格子至多一次的走法数. Input 第一行一个整数T 表示有T 组测试数据.(T <= 110) 对于每组测试数据: 第一行两个整数n, m,表示迷宫有n * m 个格子.(1

数据结构算法(1)--栈与队列

数据结构算法(1)--栈与队列 总结并记录学习数据结构过程中遇到的问题及算法. 一些常见算法: Note: 基础应用. 递归的非递归转化. 阶乘 递归实现: #include <iostream> using namespace std; int F(int n) { if (n == 0 || n == 1) return 1; else return n * F(n - 1); } int main() { int s; cin >> s; int result = F(s);

数据结构实验之栈与队列九:行编辑器

数据结构实验之栈与队列九:行编辑器 Description 一个简单的行编辑程序的功能是:接受用户从终端输入的程序或数据,并存入用户的数据区. 由于用户在终端上进行输入时,不能保证不出差错,因此,若在编辑程序中,“每接受一个字符即存入用户数据区”的做法显然不是最恰当的.较好的做法是,设立一个输入缓冲区,用以接受用户输入的一行字符,然后逐行存入用户数据区.允许用户输入出差错,并在发现有误时可以及时更正.例如,当用户发现刚刚键入的一个字符是错的时,可补进一个退格符"#",以表示前一个字符无

数据结构实验之栈与队列二:一般算术表达式转换成后缀式

数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Description 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. Input 输入一个算术表达式,以‘#’字符作为结束标志. Output 输出该表达式转换所得到的后缀式. Sample Input a*b+(c-d/e)*f# Output ab*cde/-f*+ #include <stdio.h> #include <stdlib.h> char s[100005]; //分配栈的大小 int m