数据结构(三)之队列ADT
2014-05-02 16:10
429 查看
像栈一样,队列也是表。然而,使用队列时插入在一段进行而删除则在另一端进行。队列的基本操作是Enqueue(入队),它是在表的末端(叫做队尾(rear))插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(叫做队头(front))的元素。通过数组和链表都可以实现队列,其中数组更普遍一点。
在考虑数组实现时,由于数组的大小是有限的,为了操作更多的元素,我们可以用循环数组实现,即只要Front或Rear到达数组的尾端,它又绕回到开头。在考虑队列的循环实现,有两件事情要警惕,一是检测队列是否为空很重要的,因为空时一次Dequeue操作返回一个不确定的值。二是某些程序设计人员使用不同的方法来表示队列和队尾。目前比较普遍的有三种方法:
其一是使用一个计数器记录队列中元素的总数(实际上是队列长度)。
其二是少用一个元素的空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空);
其三是另设一个布尔变量以匹别队列的空和满;
本文主要介绍前面两种方法。第三种比较简单,读者可自行实现。
1. 循环数组实现。添加一个计数器记录队列中元素的总数
2. 循环数组实现。少用一个元素的空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空)
3. 单链表实现。
队列主要的应用在于排队论。
在考虑数组实现时,由于数组的大小是有限的,为了操作更多的元素,我们可以用循环数组实现,即只要Front或Rear到达数组的尾端,它又绕回到开头。在考虑队列的循环实现,有两件事情要警惕,一是检测队列是否为空很重要的,因为空时一次Dequeue操作返回一个不确定的值。二是某些程序设计人员使用不同的方法来表示队列和队尾。目前比较普遍的有三种方法:
其一是使用一个计数器记录队列中元素的总数(实际上是队列长度)。
其二是少用一个元素的空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空);
其三是另设一个布尔变量以匹别队列的空和满;
本文主要介绍前面两种方法。第三种比较简单,读者可自行实现。
1. 循环数组实现。添加一个计数器记录队列中元素的总数
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct QueueRecord *Queue; Queue createQueue(int MaxElements); void disposeQueue(Queue Q); void enqueue(ElementType X, Queue Q); ElementType dequeue(Queue Q); struct QueueRecord { int Capacity; int Size; int Front; int Rear; ElementType *Array; }; Queue createQueue(int MaxElements) { Queue Q; Q = (Queue)malloc(sizeof(QueueRecord)); if(Q == NULL) return NULL; Q->Array = (ElementType *)malloc(MaxElements * sizeof(ElementType)); if(Q->Array == NULL) return NULL; Q->Capacity = MaxElements; Q->Size = 0; Q->Front = 0; Q->Rear = -1; return Q; } void disposeQueue(Queue Q) { if(Q != NULL) { free(Q->Array); free(Q); } return; } void enqueue(ElementType X, Queue Q) { if(Q->Size >= Q->Capacity) //队列已满 return; if(++Q->Rear == Q->Capacity) //假溢出 Q->Rear = 0; Q->Size++; Q->Array[Q->Rear] = X; return; } ElementType dequeue(Queue Q) { if(Q->Size == 0) return 0; Q->Size--; int tmp = Q->Front; Q->Front = (Q->Front + 1) % Q->Capacity; return Q->Array[tmp]; }
//循环打印 void printQueue(Queue Q) { int Rear; if(Q == NULL || Q->Size == 0) return; Rear = Q->Rear; if(Q->Front > Rear) Rear += Q->Capacity; for(int i = Q->Front;i <= Rear; ++i) { if(i >= Q->Capacity) printf("%d", Q->Array[i - Q->Capacity]); else printf("%d", Q->Array[i]); } printf("\n"); return; } int main() { Queue Q; Q = createQueue(10); if(Q == NULL) return 0; enqueue(9, Q); printf("%d\n", dequeue(Q)); for(int i=0; i<10; ++i) { enqueue(i, Q); } printQueue(Q); printf("%d\n", dequeue(Q)); printQueue(Q); enqueue(9, Q); enqueue(9, Q); printQueue(Q); disposeQueue(Q); system("pause"); return 0; }
2. 循环数组实现。少用一个元素的空间,约定入队前,测试尾指针在循环意义下加1后是否等于头指针,若相等则认为队满(注意:rear所指的单元始终为空)
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct QueueRecord *Queue; Queue createQueue(int MaxElements); void disposeQueue(Queue Q); void enqueue(ElementType X, Queue Q); ElementType dequeue(Queue Q); struct QueueRecord { int Capacity; int Front; int Rear; ElementType *Array; }; Queue createQueue(int MaxElements) { Queue Q; Q = (Queue)malloc(sizeof(QueueRecord)); if(Q == NULL) return NULL; Q->Array = (ElementType *)malloc(MaxElements * sizeof(ElementType)); if(Q->Array == NULL) return NULL; Q->Capacity = MaxElements; Q->Front = 0; Q->Rear = 0; return Q; } void disposeQueue(Queue Q) { if(Q != NULL) { free(Q->Array); free(Q); } return; } void enqueue(ElementType X, Queue Q) { int rear; rear = (Q->Rear+1) % Q->Capacity; if(rear == Q->Front) return; Q->Array[Q->Rear] = X; Q->Rear = rear; return; } ElementType dequeue(Queue Q) { if(Q->Front == Q->Rear) return 0; int tmp = Q->Front; Q->Front = (Q->Front + 1) % Q->Capacity; return Q->Array[tmp]; }
void printQueue(Queue Q) { int Rear; if(Q == NULL || Q->Front == Q->Rear) return; Rear = Q->Rear; if(Q->Front > Rear) Rear += Q->Capacity; for(int i = Q->Front;i < Rear; ++i) { if(i >= Q->Capacity) printf("%d", Q->Array[i - Q->Capacity]); else printf("%d", Q->Array[i]); } printf("\n"); return; } int main() { Queue Q; Q = createQueue(10); if(Q == NULL) return 0; enqueue(9, Q); printf("%d\n", dequeue(Q)); for(int i=0; i<10; ++i) { enqueue(i, Q); } printQueue(Q); printf("%d\n", dequeue(Q)); printQueue(Q); enqueue(9, Q); enqueue(9, Q); printQueue(Q); disposeQueue(Q); system("pause"); return 0; }
3. 单链表实现。
#include <stdio.h> #include <stdlib.h> typedef int ElementType; typedef struct Node *PtrToNode; typedef struct QueueRecord *Queue; Queue createQueue(); void disposeQueue(Queue Q); void enqueue(ElementType X, Queue Q); ElementType dequeue(Queue Q); struct QueueRecord { PtrToNode Front; PtrToNode Rear; }; struct Node { ElementType Element; PtrToNode Next; }; Queue createQueue() { PtrToNode head; head = (PtrToNode)malloc(sizeof(struct Node)); if(head == NULL) return NULL; head->Next = NULL; Queue q; q = (Queue)malloc(sizeof(struct QueueRecord)); if(q == NULL) return NULL; q->Front = head; q->Rear = head; return q; } void disposeQueue(Queue Q) { PtrToNode p; PtrToNode tmp; if(Q == NULL || Q->Front == NULL) return; p = Q->Front->Next; free(Q->Front); free(Q); while(p != NULL) { tmp = p; p = p->Next; free(tmp); } return; } void enqueue(ElementType X, Queue Q) { PtrToNode tmp; tmp = (PtrToNode)malloc(sizeof(struct Node)); if(tmp == NULL) return; tmp->Element = X; tmp->Next = NULL; Q->Rear->Next = tmp; Q->Rear = tmp; return; } ElementType dequeue(Queue Q) { PtrToNode tmp; if(Q == NULL || Q->Front == NULL || Q->Front->Next == NULL) return 0; tmp = Q->Front->Next; Q->Front->Next = tmp->Next; if(tmp == Q->Rear) Q->Rear = Q->Front; ElementType x = tmp->Element; free(tmp); return x; }
void printQueue(Queue Q) { PtrToNode p; if(Q == NULL || Q->Front == NULL || Q->Front->Next == NULL) return; p = Q->Front->Next; while(p != NULL) { printf("%d", p->Element); p = p->Next; } printf("\n"); return; } int main() { Queue Q; Q = createQueue(); if(Q == NULL) return 0; enqueue(1, Q); printf("%d\n", dequeue(Q)); printf("%d\n", dequeue(Q)); for(int i =0; i < 10; ++i) enqueue(i, Q); printQueue(Q); printf("%d\n", dequeue(Q)); printQueue(Q); enqueue(9, Q); printQueue(Q); disposeQueue(Q); system("pause"); return 0; }
队列主要的应用在于排队论。
相关文章推荐
- 数据结构-->队列的链式实现 ADT
- 数据结构-->(循环)队列 【队列的顺序实现】ADT
- 数据结构:队列ADT
- python数据结构学习笔记-2016-11-05-01-队列ADT及其实现
- HDOJ 1053 Huffman编码 自写优先队列的ADT 权当做练习数据结构
- C 基础数据结构---队列 ADT
- 数据结构-循环队列的基本实现操作
- 数据结构之队列的定义与简单实现
- 数据结构和算法学习第3天:队列的相关知识
- 数据结构:循环队列(一)设置一个标志域后的入队列和出队列的算法
- 数据结构:模板实现栈和队列
- 数据结构实现之最大索引优先队列
- 《数据结构》第三章 栈和队列 知识总结导图
- 数据结构学习笔记 --- 队列的应用举例(离散事件模拟)
- 数据结构学习——二叉堆ADT(程序化)
- 数据结构代码实现(链队列)
- 栈和队列5|逆波兰计算器 - 数据结构和算法27
- 【栈与队列】SDUT练习1—传说中的数据结构
- c++数据结构 链队列的实现
- 数据结构第七周项目4--队列数组