zoukankan      html  css  js  c++  java
  • 数据结构:链表队列的实现

    数据结构:链表队列的实现

    快速开始

      队列是一种和栈相反的,遵循先进先出原则的线性表。此文章使用链表来实现队列。

      

      如上图所示,就像一个自来水管,先进入水管的水先从水龙头出来,即Front位置的元素最先出队列,因为它们是最先入队列的。

       

    2、实现队列

      本代码是严蔚敏教授的数据结构书上面的伪代码的C语言实现代码。

      一定要多思考,多问为什么!

      首先我们定义了一些常量:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define OK 1
    #define ERROR 0
    
    typedef int QElemtype;
    typedef int status;

    2.1、对队列和节点的结构定义

      既然底层是链表,那么每个节点不仅要保存当前值,还要指向下一个节点的地址。

      对于队列来说,每次插入值都是在队尾(rear),每次取出值都是在队首(head),所以,我们一定是有两个变量来指向队头与队尾的。

      

      综上所述,我们结构定义代码如下:

    typedef struct QNode //对节点的结构定义
    {
        QElemtype data;
        struct QNode *next;
    }QNode,*QueuePtr;
    
    typedef struct{     //对队列的结构定义
        QueuePtr head;
        QueuePtr rear;
    }LinkQueue; 

    2.2、队列初始化

      初始化主要是对为队列中的两个重要节点分配空间,这里我们需要注意的是初始化时头指针和尾指针指向同一个节点。

      代码如下:

    status initQueue(LinkQueue* que) //初始化队列
    {
        que->head=que->rear=(QueuePtr)malloc(sizeof(QNode));
        if(!que->head)  //这段代码对队列里面的用户自定义数据类型进行了初始化
            return ERROR;
        return OK;
    }
    
    

    2.3、入队操作

      一定要搞清指针的概念。

      首先rear和head指向同一个元素。然后,我们使rear的next指向新元素,这样rear指向的元素(即1)的next就是新元素了。最后,我们让rear指向新元素。这样一个入队操作就完成了。

      

      代码如下:

    status enQueue(LinkQueue* que,QElemtype e)
    {
        QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
        if(!p) //若未能申请到空间,便退出
            return ERROR;
        p->data=e;
        p->next=NULL;
    
        que->rear->next = p;
        que->rear=p;
        return OK;
    }
    

      

    2.4、出队操作

      我们来思考这个过程,在下图队列中,我们出队的第一个元素是元素A,不是1。(因为1不是插入进来了的,而是我们初始化时就有的)。我们首先让*t等于head的next,即元素A。然后修改head的next指向为元素A的next。

    这样head的next就会指向元素B。出队操作就完成了。

      代码如下:

    status delQueue(LinkQueue* que,QElemtype *t)
    {
        if(que->rear==que->head)
            return ERROR; //队列为空
    
        QueuePtr p = que->head->next;
        *t=p->data;
    
        que->head->next=p->next;
        if(que->rear==p) //这个判断是 确保在清空队列的时候,让rear指针归位。
            que->rear=que->head;
        free(p);
        return OK;
    }
    

      

    2.5、回收队列

      回收可以快速取消队列,方法是让头尾碰面即可。

    status destoryQueue(LinkQueue* que) //回收队列
    {
        if(que->head)
        {
            que->rear = que->head->next;
            free(que->head);
            que->head=que->rear;
        }
        return OK;
    }
    

    2.6、遍历队列和测试方法

      提供一个简单的方法来测试链表队列。

    status viewQueue(LinkQueue* que)
    {
        if(que->rear == que->head)
            return ERROR;
        
        QueuePtr p =que->head->next;
        while(p)
        {
            printf("val:%d",p->data);
            p=p->next;
        }
        return OK;
    }
    
    int main(int argc, char **argv)
    {
        LinkQueue myQueue;
        initQueue(&myQueue);
        for(int i=1;i<=5;i++)
            enQueue(&myQueue,i);
        viewQueue(&myQueue);
        
        QElemtype a;
        for(int i=0;i<5;i++)
        {
            delQueue(&myQueue,&a);
            printf("%d
    ",a);
        }
        destoryQueue(&myQueue);
        printf("fuck !");    
        return 0;
    }    
  • 相关阅读:
    1021 个位数统计 (15 分)
    10. HttpServletResponse接口
    9. HttpServletRequest接口
    11. jQuery 获取元素尺寸
    10. jQuery 对元素属性的操作~ 一篇就够.
    7. HttpServlet类
    6 .数据库-增删改
    6. GenericServlet类
    9. jQuery 的节点操作
    8.jQuery 的 基本绑定事件操作
  • 原文地址:https://www.cnblogs.com/MrSaver/p/5942106.html
Copyright © 2011-2022 走看看