数据结构(三)之队列ADT
来源:互联网 发布:js获取unicode编码 编辑:程序博客网 时间:2024/05/29 15:38
像栈一样,队列也是表。然而,使用队列时插入在一段进行而删除则在另一端进行。队列的基本操作是Enqueue(入队),它是在表的末端(叫做队尾(rear))插入一个元素,还有Dequeue(出队),它是删除(或返回)在表的开头(叫做队头(front))的元素。通过数组和链表都可以实现队列,其中数组更普遍一点。
在考虑数组实现时,由于数组的大小是有限的,为了操作更多的元素,我们可以用循环数组实现,即只要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]);elseprintf("%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]);elseprintf("%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;}
队列主要的应用在于排队论。
0 0
- 数据结构(三)之队列ADT
- 数据结构之队列(三)
- 数据结构之栈和队列(三)
- 数据结构:队列ADT
- 数据结构-->(循环)队列 【队列的顺序实现】ADT
- C 基础数据结构---队列 ADT
- 数据结构与算法 -- 队列 ADT
- 数据结构(二)之栈ADT
- 数据结构(三)--循环队列
- 数据结构(三)队列结构
- 数据结构之字符串ADT
- 数据结构之表ADT
- 数据结构之java实现链式队列(三)
- (三)Android数据结构学习之队列
- python 数据结构三 之 栈与队列
- C Primer Plus学习 六十三 队列 ADT(三)
- 数据结构(scheme) -- 抽象数据类型(ADT) -- 队列
- 数据结构-->队列的链式实现 ADT
- 简单分析ThreadPoolExecutor实现的1.6版和1.7版之间的不同
- hi
- C++简单多态
- SDUTOJ 【1166】打印直角三角形
- [JavaScript] 三等双等的奥秘
- 数据结构(三)之队列ADT
- Windows学习心得【非模态对话框】
- 运行Java程序-设置classpath
- android(数据库分页显示)_sqlitedatabase
- poj 2226 二分图匹配的最小点覆盖建图
- 数据库设计与优化
- hdu Wooden Sticks
- agillent 买了个萌
- 好好爱护你的杯子