zoukankan      html  css  js  c++  java
  • 队列->队列的表示和实现

    文字描述

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

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

    示意图

    表示和实现

    A 链队列(链式表示)

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

      代码实现

      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("依次出队列!
    ");
     36     QElemType e;
     37     while(!DeQueue(&Q, &e)){
     38         printf("%s
    ", e.data);
     39     }
     40     printf("销毁队列!
    ");
     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);
     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
    ", 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的顺序存储的循环队列
    ", 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
    ", 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
    ", 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不能入队列!
    ", e.s);
     92         return -1;
     93     }
     94     printf("元素%s入队列!
    ", 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出队列!
    ", 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("队列是空的
    ");
    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("
    ");
    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
  • 相关阅读:
    JSP的组成
    什么是JSP
    JSP和Servlet分工图
    Linux逻辑卷管理LVM2详解
    ESXi主机和NTP server快速进行时间同步
    VMwareCLI命令参考
    使用Logminer工具分析DML和DDL操作
    TKPROF使用
    iSCSI存储设备的udev绑定 以及iscsi重启卡住解决方法
    Oracle 10g EM证书问题
  • 原文地址:https://www.cnblogs.com/aimmiao/p/10719127.html
Copyright © 2011-2022 走看看