队列的顺序存储结构和链式存储结构
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表(在队尾进行插入操作,在对头进行删除操作)。
与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表。
与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础。
队列的链式存储结构
队列既可以用链表实现,也可以用顺序表实现。跟栈相反的是,栈一般我们用顺序表来实现,而队列我们常用链表来实现,简称为链队列。
- typedef struct QNode {
- ElemType data;
- struct QNode *next;
- } QNode, *QueuePrt;</span>
- <span style="font-family:KaiTi_GB2312;font-size:18px;"> typedef struct {
- QueuePrt front; //队头
- QueuePrt rear; //队尾指针
- } LinkQueue;
队列的链式存储结构
空队列时,front和rear都指向头结点。
创建一个队列
创建一个队列要完成两个任务:一是在内存中创建一个头结点,二是将队列的头指针和尾指针都指向这个生成的头结点,因为此时是空队列。
- initQueue(LinkQueue *q){
- q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
- if( !q->front )
- exit(0);
- q->front->next = NULL;
- }
入队列操作
- //入队列操作
- InsertQueue(LinkQueue *q, ElemType e){
- QueuePtr p;
- p = (QueuePtr)malloc(sizeof(QNode));
- if( p == NULL )
- exit(0);
- p->data = e;
- p->next = NULL;
- q->rear->next = p;
- q->rear = p;
- }
出队列操作
出队列操作是将队列中的第一个元素移出,队头指针不发生改变,改变头结点的next指针即可。
如果原队列只有一个元素,那么我们就应该处理一下队尾指针。
出队列操作
DeleteQueue(LinkQueue *q, ELemType *e){
- QueuePtr p;
- if( q->front == q->rear )
- return;
- p = q->front->next;
- *e = p->data;
- q->front->next = p->next;
- if( q->rear == p )
- q->rear = q->front;
- free(p);
- }
销毁一个队列
由于链队列建立在内存的动态区,因此当一个队列不再有用时应当把它及时销毁掉,以免过多地占用内存空间。
- DestroyQueue(LinkQueue *q){
- while( q->front )
- {
- q->rear = q->front->next;
- free( q->front );
- q->front = q->rear;
- }
- }
队列的顺序存储结构
我们假设一个队列有n个元素,则顺序存储的队列需建立一个大于n的存储单元,并把队列的所有元素存储在数组的前n个单元,数组下标为0的一端则是队头。
入队列操作其实就是在队尾追加一个元素,不需要任何移动,时间复杂度为O(1)。
出队列则不同,因为我们已经架设下标为0的位置是队列的队头,因此每次出队列操作所有元素都要向前移动。
在现实中也是如此,一群人在排队买火车票,前边的人买好了离开,后面的人就要全部向前一步补上空位。
可是我们研究数据结构和算法的一个根本目的就是要想方设法提高我们的程序的效率,按刚才的方式,出队列的时间复杂度是O(n),效率大打折扣!
如果我们不去限制队头一定要在下标为0的位置,那么出队列的操作就不需要移动全体元素。
但是这样也会出现一些问题,例如按下边的情形继续入队列,就会出现数组越界的错误。
可事实上我们有0和1两个下标还空着,这叫假溢出。
循环队列(在实际中应用相当广泛)
我们再想想,要解决假溢出的办法就是如果后面满了,就再从头开始,也就是头尾相接的循环。
循环队列它的容量是固定的,并且它的队头和队尾指针都可以随着元素入、出队列而发生改变,这样循环队列逻辑上就好像是一个环形存储空间。
但要注意的是,在实际的内存当中,不可能有真正的环形存储区,我们只是用顺序表模拟出来的逻辑上的循环。
于是我们发觉了,似乎循环队列的实现只需要灵活改变front和rear指针即可。
也就是让front或rear指针不断加1,即使超出了地址范围,也会自动从头开始。我们可以采取取模运算处理:(这个运算在数据结构中特别常见,也特别重要!)
(rear+1) % QueueSize
(front+1) % QueueSize
取模就是取余数的意思,他取到的值永远不会大于除数。
定义一个循环队列
- #define MAXSIZE 100
- typedef struct{
- ElemType *base; // 用于存放内存分配基地址,这里你也可以用数组存放
- int front;
- int rear;
- }
- 初始化一个循环队列
- initQueue(cycleQueue *q){
- q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
- if( !q->base )
- exit(0);
- q->front = q->rear = 0;
- }
- 入队列操作
- InsertQueue(cycleQueue *q, ElemType e){
- if( (q->rear+1)%MAXSIZE == q->front )
- return; // 队列已满
- q->base[q->rear] = e;
- q->rear = (q->rear+1) % MAXSIZE;
- }
- 出队列操作
- DeleteQueue(cycleQueue *q, ElemType *e){
- if( q->front == q->rear )
- return ; // 队列为空
- *e = q->base[q->front];
- q->front = (q->front+1) % MAXSIZE;
- }
![](http://avatar.csdn.net/0/4/B/3_qq_41169997.jpg)
-
队列的顺序存储结构
- generalhking
- 2013年02月28日 14:25
- 1209
队列是一种先进先出(First In First Out)的线性表,简称FIFO。在队尾进行插入(front),在队头进行删除(rear)。以下以一个循环队列为例进行实现。循环队列空的条件...
-
队列的顺序存储结构——循环队列 图解和代码实现
- ggxxkkll
- 2013年03月11日 23:07
- 9707
队列的顺序存储结构——循环队列循环队列的长度为(rear-front+QueueSize)%QueueSize队空的条件: front=rear队满的条件是: (rear+1)%Queue...
-
数据结构:队列的顺序存储结构(循环队列)
- Sandeldeng
- 2016年11月01日 21:14
- 934
队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。是一种先进先出的线性表(FIFO)。允许插入的一端称为队尾,允许删除的一端称为队头。我们在《栈的顺序存储结构》中发现,栈操...
-
队列的顺序存储结构
- hustspy1990
- 2010年04月09日 19:18
- 716
队列的顺序存储结构称为顺序队列,顺序队列实际上是运算受限的顺序表。与顺序栈类似,在队列的顺序存储结构中,用一组地址连续的存储单元一次存放从队列头到队列尾的元素。指针front和rear被分别用来队列头...
-
队列的顺序存储结构
- BAT_os
- 2015年11月26日 23:53
- 987
队列的顺序存储结构相对于链式存储结构较为复杂,本文重点介绍队列顺序结构。下面简单的谈两个问题:1.由于是顺序队列,很容易想到用数组来存储元素,假如一个队列的长度是10,就是一下可以放入10个元素,当...
-
队列的顺序存储结构
- tianzeyu1992
- 2015年11月11日 16:44
- 241
队列 1.环形,队头front,队尾rear 2.队头所指的data位置不放值 3.队满条件:(rear+1)%MaxSize == front 4.队空条件:reat == front 5...
-
循环队列-顺序存储-c语言实现
- u010187139
- 2015年07月03日 16:11
- 803
/* 循环队列-线性表-顺序结构 */ #include#define OK 1;#define ERROR 0;#define MAXSIZE 20typedef int QEle...
-
队列的链式存储结构
- dongyanxia1000
- 2016年08月11日 17:00
- 453
1、队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,简称为链队列。---- 为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端结点。---- 空队列时...
-
队列的顺序存储实现—循环队列
- chewbee
- 2015年04月17日 21:37
- 1975
队列(queue)是一种只允许在一端插入元素,而在另一端删除元素的线性表。它是一种先进先出(First In First Out,FIFO)的线性表。我们把允许插入的一端称为队尾,允许删除元素的一端称...
-
栈的顺序存储结构和链式存储结构
- scu_daiwei
- 2013年01月24日 11:50
- 12155
栈(stack)很多人都不会太陌生,说到栈大家一定会想到一句话:后进先出(Last In First Out)。这句话就是栈的一个本质特点,其实栈就是一个只能在一端进行插入、删除的特殊的线性表。栈有栈...
-
线性表之顺序存储结构和链式存储结构
- qq_31151129
- 2016年07月21日 20:03
- 1138
一、顺序存储结构线性表几种基本操作的思路1、插入算法: 1)插入位置不合理,抛出异常 2)线性表长度超过(>=)数组长度,抛出异常或者是动态增加数组容量(效率会...
-
队列的顺序存储和链式表示方法-数据结构学习笔记2.3
1,顺序存储时我们常用循环队列,为了区分队列满和空,我们最多只用MAX-1个空间队列空:q->rear=q->front队列满:q->front=(q->rear+1)%MAX typed...- qq_26046771
- 2017年03月28日 09:35
- 184
-
线性结构的顺序存储和链式存储的实现代码(一)
线性结构的物理存储主要有两种方式:顺序存储和链式存储。线性结构中一个数据元素是没有什么意义的,所有的数据元素构成一个整体才有意义。为了对这个整体有一个大方为的管理,所以,我们应该建立关于这个整体的头,...- jiben2qingshan
- 2012年06月04日 17:14
- 891
-
数据结构2----线性表顺序存储和链式存储的实现(霜之小刀)
所谓线性表,其实就是具有“线”一样性质的表,所谓线一样的性质,也就是具有n个数据元素的优先序列。其中n>=0...- lihn1987
- 2017年02月06日 15:00
- 803
文章分类
文章存档
他的热门文章
- 哈希表(散列表)原理详解
46104
- C++ 中vector的使用方法
20507
- vector::erase() vector中如何删除元素?
15287
- Boost库各个版本下载地址
10499
- 队列的顺序存储结构和链式存储结构
10026
联系我们
- 网站客服
- 微博客服
- webmaster@csdn.net
- 400-660-0108