队列->队列的表示和实现

文字描述

  队列是和栈相反,队列是一种先进先出(first in first out,缩写FIFO)的线性表,它只允许在表的一端进行插入,而在另一端进行删除。和生活中的排队相似,最早进入队列的元素最早离开。在队列中,允许插入的一端加队尾,允许删除的一端叫队头。

  另外除了栈和队列,还有一种限定性数据结构是双端队列,它是一种插入和删除操作在表的两端进行的线性表。可以用一个铁道铁轨网络来比喻双端队列。

示意图

表示和实现

A 链队列(链式表示)

  用链表表示的队列简称链队列。一个链队列需要分别指向队头和队为的指针才能唯一确定。一般,为了操作方便,会给链队列添加一个不存数据的头结点,并令头结点的next指针指向头结点。由此,空的链队列的判决条件为头指针和尾指针均指向头结点。

扫描二维码关注公众号,回复: 5912359 查看本文章

  代码实现

  1 //
  2 // Created by lady on 19-4-4.
  3 //
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include <string.h>
  7 
  8 typedef struct QElemType{
  9     char data[10];
 10 }QElemType;
 11 
 12 typedef struct QNode{
 13     QElemType data;
 14     struct QNode *next;
 15 }QNode, *QueuePtr;
 16 typedef struct LinkQueue{
 17     QueuePtr front;
 18     QueuePtr rear;
 19 }LinkQueue;
 20 
 21 static int InitQueue(LinkQueue *Q);
 22 static int CreateQueue(LinkQueue *Q, int n);
 23 static int DestoryQueue(LinkQueue *Q);
 24 static int EnQueue(LinkQueue *Q, QElemType e);
 25 static int DeQueue(LinkQueue *Q, QElemType *e);
 26 static int QueueTraverse(LinkQueue Q);
 27 
 28 int main(int argc, char *argv[])
 29 {
 30     LinkQueue Q;
 31     int i = 0;
 32     if(CreateQueue(&Q, 5)<0){
 33         return -1;
 34     }
 35     printf("依次出队列!\n");
 36     QElemType e;
 37     while(!DeQueue(&Q, &e)){
 38         printf("%s\n", e.data);
 39     }
 40     printf("销毁队列!\n");
 41     DestoryQueue(&Q);
 42     return 0;
 43 }
 44 
 45 
 46 
 47 static int InitQueue(LinkQueue *Q)
 48 {
 49     if(Q == NULL){
 50         return -1;
 51     }
 52     Q->front = (QueuePtr)malloc(sizeof(QNode));
 53     Q->front->next = NULL;
 54     Q->rear = Q->front;
 55     if(Q->front == NULL){
 56         return -1;
 57     }else{
 58         return 0;
 59     }
 60 }
 61 
 62 static int CreateQueue(LinkQueue *Q, int n)
 63 {
 64     printf("创建一个长度为%d,以链式存储的链队列!\n", n);
 65     if(InitQueue(Q)<0){
 66         return -1;
 67     }
 68     int i = 0;
 69     QElemType e;
 70     for(i=0; i<n; i++){
 71         printf("输入第%d个元素:", i+1);
 72         scanf("%s[^\\n]", e.data);
 73         if(EnQueue(Q, e)<0){
 74             return -1;
 75         }
 76     }
 77     return 0;
 78 }
 79 
 80 static int DestoryQueue(LinkQueue *Q)
 81 {
 82     QueuePtr p = Q->front->next;
 83     QueuePtr q = NULL;
 84     while(p){
 85         q = p;
 86         p = p->next;
 87         free(q);
 88     }
 89     if(Q->front){
 90         free(Q->front);
 91         Q->front = NULL;
 92     }
 93     return 0;
 94 }
 95 static int EnQueue(LinkQueue *Q, QElemType e)
 96 {
 97     QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
 98     if(p == NULL){
 99         return -1;
100     }
101     p->data = e;
102     p->next = NULL;
103     Q->rear->next = p;
104     Q->rear = p;
105     return 0;
106 }
107 
108 static int DeQueue(LinkQueue *Q, QElemType *e)
109 {
110     if(Q->front == Q->rear){
111         return -1;
112     }
113     QueuePtr p = Q->front->next;
114     (*e) = p->data;
115     Q->front->next = p->next;
116     if(p == Q->rear){
117         Q->rear = Q->front;
118     }
119     free(p);
120     return 0;
121 }
122 
123 static int QueueTraverse(LinkQueue Q)
124 {
125     QueuePtr p = Q.front->next;
126     while(p){
127         printf("%s\n", p->data.data);
128         p = p->next;
129     }
130     return 0;
131 }
链队列

  代码运行

 1 /home/lady/CLionProjects/untitled/cmake-build-debug/untitled
 2 创建一个长度为5,以链式存储的链队列!
 3 输入第1个元素:a1
 4 输入第2个元素:a2
 5 输入第3个元素:a3
 6 输入第4个元素:a4
 7 输入第5个元素:a5
 8 依次出队列!
 9 a1
10 a2
11 a3
12 a4
13 a5
14 销毁队列!
15 
16 Process finished with exit code 0

B 循环队列(顺序表示)

  和顺序栈类似,除了用一组地址连续的存储单元依次存放从队头到队尾的元素外,需设两个指针front和rear分别指向队头元素和队尾元素的位置。一般,为了充分利用空间,会将顺序队列设置为循环模式。在循环队列中,判断队列空间是否为”空“还是”满”。可有两种处理方法:1)单独设置一个标志位以区分队列是否为满 2)少用一个元素空间,约定以”队列头指针在队列指针的下一位置(指环状的下一个位置)上”作为队列满状态的标志。

  代码实现

  1 //
  2 // Created by lady on 19-4-4.
  3 //
  4 
  5 #include <stdio.h>
  6 #include <stdlib.h>
  7 #include <string.h>
  8 
  9 //----循环队列----队列的顺序存储结构
 10 #define MAXQSIZE 6  //循环队列的最大长度
 11 typedef struct QElemType{
 12     char s[10];
 13 }QElemType;
 14 typedef struct SqQueue{
 15     QElemType *base;//初始化的动态分配存储空间
 16     int front; //头指针,队列不为空的话指向队列头元素
 17     int rear; //尾指针,队列不为空的话指向队列尾元素的下一个位置
 18 }SqQueue;
 19 
 20 //初始化队列
 21 static int InitQueue(SqQueue *Q);
 22 //求队列长度
 23 static int QueueLength(SqQueue Q);
 24 //入队列
 25 static int EnQueue(SqQueue *Q, QElemType e);
 26 //出队列
 27 static int DeQueue(SqQueue *Q, QElemType *e);
 28 //遍历队列
 29 static int TraverseQueue(SqQueue Q);
 30 
 31 static int CreateQueue(SqQueue *Q, int l){
 32     if(InitQueue(Q) < 0){
 33         return 0;
 34     }
 35     printf("创建一个长度为%d的顺序存储的循环队列\n", l);
 36 
 37     QElemType e;
 38     int i = 0;
 39     for(i=0; i<l; i++){
 40         printf("输入第(%d)个数据元素:", i+1);
 41         memset(e.s, 0, sizeof(e.s));
 42         scanf("%s[^\\n]", e.s);
 43         EnQueue(Q, e);
 44     }
 45     return 0;
 46 }
 47 
 48 int main(int argc, char *argv[])
 49 {
 50     QElemType e;
 51     SqQueue Q;
 52     if(CreateQueue(&Q, 5) < 0){
 53         return -1;
 54     }
 55     printf("队列长度为%d\n", QueueLength(Q));
 56     TraverseQueue(Q);
 57 
 58     snprintf(e.s, sizeof(e.s), "%s", "A6");
 59     EnQueue(&Q, e);
 60 
 61     DeQueue(&Q, &e);
 62     DeQueue(&Q, &e);
 63 
 64     snprintf(e.s, sizeof(e.s), "%s", "A6");
 65     EnQueue(&Q, e);
 66 
 67     TraverseQueue(Q);
 68     return 0;
 69 }
 70 
 71 static int InitQueue(SqQueue *Q)
 72 {
 73     Q->base = (QElemType *)malloc(MAXQSIZE*sizeof(QElemType));
 74     if(!Q->base){
 75         return -1;
 76     }else{
 77         printf("队列初始化成功,队列可保存的最大元素个数为%d\n", MAXQSIZE);
 78         Q->front = Q->rear = 0;
 79         return 0;
 80     }
 81 }
 82 
 83 static int QueueLength(SqQueue Q)
 84 {
 85     return ((Q.rear-Q.front+MAXQSIZE) % MAXQSIZE);
 86 }
 87 
 88 static int EnQueue(SqQueue *Q, QElemType e)
 89 {
 90     if((Q->rear+1) % MAXQSIZE == Q->front){
 91         printf("队列已满,元素%s不能入队列!\n", e.s);
 92         return -1;
 93     }
 94     printf("元素%s入队列!\n", e.s);
 95     Q->base[Q->rear] = e;
 96     Q->rear = (Q->rear+1) % MAXQSIZE;
 97     return 0;
 98 }
 99 
100 static int DeQueue(SqQueue *Q, QElemType *e)
101 {
102     if(Q->front == Q->rear){
103         return -1;
104     }
105     (*e) = Q->base[Q->front];
106     printf("元素%d:%s出队列!\n", Q->front, (*e).s);
107     Q->front = (Q->front+1) % MAXQSIZE;
108     return 0;
109 }
110 
111 static int TraverseQueue(SqQueue Q)
112 {
113     printf("遍历:");
114     if(Q.rear == Q.front){
115         printf("队列是空的\n");
116     }
117     int i = Q.front;
118     do{
119         printf("%d:%s ", i, Q.base[i].s);
120         i = (i+1)%MAXQSIZE;
121         if(i == Q.rear){
122             break;
123         }
124     }while(1);
125     printf("\n");
126 }
循环队列

  代码运行

/home/lady/CLionProjects/untitled/cmake-build-debug/untitled
队列初始化成功,队列可保存的最大元素个数为6
创建一个长度为5的顺序存储的循环队列
输入第(1)个数据元素:a1
元素a1入队列!
输入第(2)个数据元素:a2
元素a2入队列!
输入第(3)个数据元素:a3
元素a3入队列!
输入第(4)个数据元素:a4
元素a4入队列!
输入第(5)个数据元素:a5
元素a5入队列!
队列长度为5
遍历:0:a1 1:a2 2:a3 3:a4 4:a5 
队列已满,元素A6不能入队列!
元素0:a1出队列!
元素1:a2出队列!
元素A6入队列!
遍历:2:a3 3:a4 4:a5 5:A6 

Process finished with exit code 0

猜你喜欢

转载自www.cnblogs.com/aimmiao/p/10719127.html