暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

数据结构(严蔚敏C语言版)——队列(链队列)

编程Cookbook 2020-03-10
33

点击上方蓝字关注我!

如果有错误或者理解不到位的地方还请各位指正!

数据结构的相关问题,可以参考笔者写的系列数据结构文章,或者加我交流!

声明:以下内容是对清华大学出版社出版,由严蔚敏和吴伟民编著的图书《数据结构》(C语言版)的代码实现。
图书PDF版本可移步公众号【李歘歘】回复电子书领取。
《数据结构》(C语言版)是各大高校计算机有关专业的指定教材,还是计算机考研的统考专业课数据结构指定的参考书籍,数据结构作为408专业课的重中之重,值得大家重视。

上次说到了栈的链栈,今天我们来说一下有关队列的链队列,相关知识点可以先了解一下。


书中位置(页码):P60-P62

函数定义及说明:

    Status InitQueue(LinkQueue &Q)  //初始化
    Status EnQueue(LinkQueue &Q,QElemType e)  //入队 
    void CrQueue(LinkQueue &Q,int n)  //创建队列 (重复调用入队操作) 
    Status DeQueue(LinkQueue &Q,QElemType e)  //出队
    Status QueueTraverse(LinkQueue Q)  //遍历
    Status QueueEmpty(LinkQueue Q)  //判空
    int QueueLength(LinkQueue Q)  //获取队列元素个数
    Status GetHead(LinkQueue Q,QElemType e)  //获取队头元素
    Status ClearQueue(LinkQueue &Q)  //置空
    Status DestoryQueue(LinkQueue &Q)  //销毁

    程序代码:

      #include<cstdio>
      #include<cstdlib>
      #define QElemType int
      #define Status int

      using namespace std;
      //链队的结构 (数据域和指针域)
      typedef struct QNode{
      QElemType data; //数据域
      struct QNode *next; //指针域
      }QNode, *QueuePtr;
      //链队头尾指针结构
      typedef struct {
      QueuePtr front; //队头指针(出队)
      QueuePtr rear; //队尾指针 (入队)
      }LinkQueue;

      //初始化
      Status InitQueue(LinkQueue &Q){
      Q.front = Q.rear = new QNode; //新建头结点,队头队尾均指向它
      if(!Q.front){
      printf("队列分配内存失败");
      return 0;
      }
      Q.front->next = NULL;
      return 0;
      }

      //入队
      Status EnQueue(LinkQueue &Q,QElemType e){
      QueuePtr p = new QNode; //新建结点
      if(!p){
      printf("分配内存失败");
      return 0;
      }
      p->data = e; //新结点赋值
      p->next = NULL; //新结点的指针域为空,(队尾插入)
      Q.rear->next = p; //队尾指针指向p
      Q.rear = p; //队尾指针后移
      printf("入队成功\n");
      return 0;
      }

      //创建队列 (重复调用入队操作)
      void CrQueue(LinkQueue &Q,int n){
      InitQueue(Q); //初始化队列
      for(int i=0;i<n;i++){ //循环n次EnQueue操作
      int e;
      scanf("%d",&e);
      EnQueue(Q,e);
      }
      printf("创建成功\n");
      }

      //出队
      Status DeQueue(LinkQueue &Q,QElemType e){
      if(Q.front == Q.rear){ //判空
      printf("队列为空\n");
      return 0;
      }
      QueuePtr p = Q.front->next; //新建结点获取队头元素
      e = p->data; //给e赋值
      Q.front->next = p->next; //出队,重新赋值队头结点(Q.front->next)为下一个结点
      /**队列中的最后一个结点出队,会导致队列尾指针丢失,
      应该将队尾指针重新赋值(指向头指针)
      */if(Q.rear == p)
      Q.rear = Q.front;
      free(p);
      printf("%d出队成功\n",e);
      return 0;
      }

      //遍历
      Status QueueTraverse(LinkQueue Q){
      printf("遍历开始:");
      QueuePtr p = Q.front->next; //队头元素之前有一个空的头结点
      while(p != Q.rear->next){ //当p没有到达队尾指针
      printf("%d ",p->data);
      p = p->next;
      }
      printf("\n");
      return 0;
      }

      //判空
      Status QueueEmpty(LinkQueue Q){
      if(Q.front == Q.rear){
      printf("队列为空\n");
      return true;
      }else{
      printf("队列不为空\n");
      return false;
      }
      }

      //获取队列元素个数
      int QueueLength(LinkQueue Q){
      QueuePtr p = Q.front->next;
      int count=0;
      while(p != Q.rear->next){ //当p没有到达队尾指针
      p = p->next;
      count++;
      }
      printf("队列元素个数为:%d\n",count);

      }

      //获取队头元素
      Status GetHead(LinkQueue Q,QElemType e){
      if(Q.front == Q.rear){
      printf("队列为空\n");
      return 0;
      }
      e = Q.front->next->data; //队头元素之前有一个空的头结点
      printf("队头元素为:%d\n",e);
      return 0;
      }

      //置空
      Status ClearQueue(LinkQueue &Q){
      Q.rear = Q.front;
      printf("置空操作成功\n");
      return 0;
      }

      //销毁
      Status DestoryQueue(LinkQueue &Q){
      while(Q.front){
      Q.rear = Q.front->next; //将队尾指针每次都指向队头指针的下一个结点
      free(Q.front); //释放队头指针
      Q.front = Q.rear; //队头指针重新赋值
      }
      printf("销毁成功\n");
      return 0;
      }


      int main(){
      int n;
      QElemType value1,value2;
      LinkQueue Q;
      printf("请输入队列元素个数:");
      scanf("%d",&n);
      CrQueue(Q,n);
      GetHead(Q,value1);
      QueueLength(Q);
      QueueTraverse(Q);
      DeQueue(Q,value2);
      QueueTraverse(Q);
      ClearQueue(Q);
      QueueEmpty(Q);
      QueueTraverse(Q);
      DestoryQueue(Q);
      return 0;
      }
      ————————————————
      版权声明:本文为CSDN博主「李歘歘」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
      原文链接:https://lichuachua.blog.csdn.net/article/details/104539116

      运行结果:

      「往  •  期  •  精  •  选」

          

      程序员自学攻略——分享珍藏多年的学习网站

      在B站,我看到了不同的技术人生

      原谅我,是我不配!!!

      技术分享的优势——写文章半年的收获

      考研VS就业——选一条适合自己的路

      这些经典排序,你必须掌握
      最短路径——Dijkstra算法这一篇就够了

      全源最短路径问题——Floyd算法

      在看点这里
      文章转载自编程Cookbook,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

      评论