队列(queue )是一种先进先出(first in first out,简称 FIFO表)的线性表。
它只允许在表的一端进行插入,而在另一端删 除元素。
在队列中,允许插入的一端叫做队尾(rear),允许删除的一端 称为队头(front)。
一、队列的顺序表示和实现,循环队列(数组)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <malloc.h> 4 5 #define OK 1 6 #define ERROR 0 7 #define OVERFLOW -1 8 #define MAXQSIZE 100 //最大队列长度 9 10 typedef int Status; 11 typedef int QElemType; 12 13 /* 0.队列结构体 */ 14 typedef struct { 15 QElemType *base; // 指针(指向动态分配存储空间) 16 int front; //头指针,若队列不空, 17 //指向队列头元素 18 int rear; //尾指针,若队列不空, 19 //指向队列尾元素的下 一个位置 20 }SqQueue; //定义循环队列类型 21 22 /* 1.队列Q初始化(构造一个空队列Q) */ 23 Status InitQueue (SqQueue &Q) { 24 Q.base = (QElemType *) malloc(MAXQSIZE *sizeof (QElemType)); 25 if (!Q.base) exit (OVERFLOW);// 存储分配失败 26 Q.front = Q.rear = 0; //队列为空(数组下标均为0) 27 return OK; 28 } 29 30 /* 2.队列Q的队尾插入元素e*/ 31 Status EnQueue (SqQueue &Q, QElemType e) { 32 if ((Q.rear+1) % MAXQSIZE == Q.front) 33 return ERROR; //队列满 rear+1 == front 34 Q.base[Q.rear] = e; //插入队尾 35 Q.rear = (Q.rear+1) % MAXQSIZE; //队尾指针更新 rear+1 36 return OK; 37 } 38 39 /* 3.删除队列Q的队头元素 */ 40 Status DeQueue (SqQueue &Q, QElemType &e) { 41 if (Q.front == Q.rear) return ERROR; //空队列 front == rear 42 e = Q.base[Q.front]; //返回删除的元素 43 Q.front = (Q.front+1) % MAXQSIZE; //删除元素(更新队头指针 front+1) 44 return OK; 45 } 46 47 /* 测试代码 */ 48 int main() 49 { 50 int array[10] = {0}; 51 SqQueue Q; //创建一个队列变量 52 InitQueue(Q);//队列初始化(分配空间,构造空队列) 53 for(int i=0; i<10; ++i) 54 EnQueue(Q,i+1); //队列插入元素 55 for(int j=0; j<10; ++j) 56 DeQueue(Q,array[j]); //删除队列元素,到数组array 57 for(int k=0; k<10; ++k) //输出数组元素 58 printf("%3d",array[k]); 59 printf(" "); 60 return 0; 61 }
1 //浙大数据结构 顺序队列 2 typedef int Position; 3 struct QNode { 4 ElementType *Data; /* 存储元素的数组 */ 5 Position Front, Rear; /* 队列的头、尾指针 */ 6 int MaxSize; /* 队列最大容量 */ 7 }; 8 typedef struct QNode *Queue; 9 10 Queue CreateQueue( int MaxSize ) 11 { 12 Queue Q = (Queue)malloc(sizeof(struct QNode)); 13 Q->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType)); 14 Q->Front = Q->Rear = 0; 15 Q->MaxSize = MaxSize; 16 return Q; 17 } 18 19 bool IsFull( Queue Q ) 20 { 21 return ((Q->Rear+1)%Q->MaxSize == Q->Front); 22 } 23 24 bool AddQ( Queue Q, ElementType X ) 25 { 26 if ( IsFull(Q) ) { 27 printf("队列满"); 28 return false; 29 } 30 else { 31 Q->Rear = (Q->Rear+1)%Q->MaxSize; 32 Q->Data[Q->Rear] = X; 33 return true; 34 } 35 } 36 37 bool IsEmpty( Queue Q ) 38 { 39 return (Q->Front == Q->Rear); 40 } 41 42 ElementType DeleteQ( Queue Q ) 43 { 44 if ( IsEmpty(Q) ) { 45 printf("队列空"); 46 return ERROR; 47 } 48 else { 49 Q->Front =(Q->Front+1)%Q->MaxSize; 50 return Q->Data[Q->Front]; 51 } 52 }
二、队列的链式表示和实现,链队列(链表)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <malloc.h> 4 5 #define OK 1 6 #define ERROR 0 7 #define OVERFLOW -1 8 #define MAXQSIZE 100 //最大队列长度 9 10 typedef int Status; 11 typedef int QElemType; 12 typedef struct Node QNode; //结点类型 13 typedef struct Node* QueuePtr;//结点指针 14 struct Node { //定义结点 15 QElemType data; //结点data 16 QueuePtr next; //结点next指针 17 }; 18 19 /* 0.队列结构体 */ 20 typedef struct { 21 QueuePtr front; // 队头指针 22 QueuePtr rear; // 队尾指针 23 } LinkQueue; // 链队列类型 24 25 /* 1.队列Q初始化(构造一个空队列Q) */ 26 Status InitQueue (LinkQueue &Q) { 27 //队列的队头、队尾指向队头结点(空队列) 28 Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode)); 29 if (!Q.front) exit (OVERFLOW);//存储分配失败 30 Q.front->next = NULL;//头指针置空 31 return OK; 32 } 33 34 /* 2.销毁队列Q */ 35 Status DestroyQueue (LinkQueue &Q) { 36 Q.front = Q.front->next;//带头结点的队列 37 while (Q.front) 38 { 39 Q.rear = Q.front->next; 40 free (Q.front) ; 41 Q.front = Q.rear; 42 } 43 return OK; 44 } 45 46 /* 3.队列Q的队尾插入元素e*/ 47 Status EnQueue (LinkQueue &Q, QElemType e) { 48 QueuePtr p = (QueuePtr) malloc (sizeof (QNode)); 49 if(!p) exit (OVERFLOW); //存储分配失败 50 p->data = e; 51 p->next = NULL; //新结点p->next置为NULL 52 Q.rear->next = p;//插入队列 53 Q.rear = p; //更新队尾 54 return OK; 55 } 56 57 /* 3.删除队列Q的队头元素 */ 58 Status DeQueue (LinkQueue &Q, QElemType &e) { 59 if (Q.front == Q.rear) return ERROR; //队列为空 60 QueuePtr p = Q.front->next; 61 e = p->data; 62 Q.front->next = p->next; //删除队头元素(其后继元素挂到队列头结点) 63 if (Q.rear == NULL) Q.rear = Q.front; //队尾空,队列置空 64 free (p); //释放删除的对头元素 65 return OK; 66 } 67 68 /* 测试代码 */ 69 int main() 70 { 71 int array[10] = {0}; 72 LinkQueue Q; //创建一个队列变量 73 InitQueue(Q);//队列初始化(分配空间,构造空队列) 74 for(int i=0; i<10; ++i) 75 EnQueue(Q,i+1); //队列插入元素 76 for(int j=0; j<10; ++j) 77 DeQueue(Q,array[j]); //删除队列元素,到数组array 78 for(int k=0; k<10; ++k) //输出数组元素 79 printf("%3d",array[k]); 80 printf(" "); 81 return 0; 82 }
1 /* 只有尾指针的循环队列 */ 2 #include <stdio.h> 3 #include <malloc.h> 4 5 #define OK 1 6 #define ERROR 0 7 8 typedef int QElemType, Status; 9 typedef struct LinkQueueNode* LinkQueuePTR; 10 11 /* 0.结点 */ 12 struct LinkQueueNode{ 13 QElemType e; 14 LinkQueuePTR next; 15 }; 16 17 /* 1. 初始化队列*/ 18 Status InitQueue(LinkQueuePTR *rear) 19 { 20 LinkQueuePTR p; 21 p = (LinkQueuePTR)malloc(sizeof(struct LinkQueueNode)); 22 if(p == NULL) 23 return ERROR; 24 25 p->next = p; 26 *rear = p; 27 return OK; 28 } 29 /* 2. 队列是否为空*/ 30 Status isEmpty(LinkQueuePTR rear) 31 { 32 if(rear == NULL) 33 return ERROR; 34 return rear == rear->next ? OK : ERROR; 35 } 36 /* 3. 进队*/ 37 Status enqueue(LinkQueuePTR *rear,QElemType e) 38 { 39 LinkQueuePTR p; 40 p = (LinkQueuePTR)malloc(sizeof(struct LinkQueueNode)); 41 if(p == NULL) 42 return ERROR; 43 44 p->e=e; 45 p->next = (*rear)->next; 46 (*rear)->next = p; 47 *rear = p; 48 return OK; 49 } 50 /* 4. 出队*/ 51 Status dequeue(LinkQueuePTR *rear,QElemType *e) 52 { 53 if(isEmpty(*rear)) 54 return ERROR; 55 56 LinkQueuePTR front; 57 front = (*rear)->next->next; 58 59 if(front == *rear){/* 是否只一个结点 */ 60 *rear = front->next; 61 (*rear)->next = *rear; 62 } 63 else{ 64 (*rear)->next->next = front->next; 65 } 66 67 *e = front->e; 68 free(front); 69 return OK; 70 } 71 72 /* 测试代码 */ 73 int main() 74 { 75 LinkQueuePTR rear = NULL; 76 QElemType e; 77 int n = 5; 78 /* 初始化只有尾指针的循环队列 */ 79 InitQueue(&rear); 80 /* 队列输入数据(进队) */ 81 for(int i=0; i<n; ++i){ 82 scanf("%d",&e); 83 enqueue(&rear,e); 84 } 85 /* 出队 */ 86 while(!isEmpty(rear)) 87 { 88 dequeue(&rear,&e); 89 printf("%5d",e); 90 } 91 return 0; 92 }
1 //浙大数据结构 链队列 2 typedef struct Node *PtrToNode; 3 struct Node { /* 队列中的结点 */ 4 ElementType Data; 5 PtrToNode Next; 6 }; 7 typedef PtrToNode Position; 8 9 struct QNode { 10 Position Front, Rear; /* 队列的头、尾指针 */ 11 int MaxSize; /* 队列最大容量 */ 12 }; 13 typedef struct QNode *Queue; 14 15 bool IsEmpty( Queue Q ) 16 { 17 return ( Q->Front == NULL); 18 } 19 20 ElementType DeleteQ( Queue Q ) 21 { 22 Position FrontCell; 23 ElementType FrontElem; 24 25 if ( IsEmpty(Q) ) { 26 printf("队列空"); 27 return ERROR; 28 } 29 else { 30 FrontCell = Q->Front; 31 if ( Q->Front == Q->Rear ) /* 若队列只有一个元素 */ 32 Q->Front = Q->Rear = NULL; /* 删除后队列置为空 */ 33 else 34 Q->Front = Q->Front->Next; 35 FrontElem = FrontCell->Data; 36 37 free( FrontCell ); /* 释放被删除结点空间 */ 38 return FrontElem; 39 } 40 }