链表实现队列操作

时间:2022-12-01 17:35:06

使用链表实现队列,需要一个对头指向对列头部管理数据出对,一个队尾管理数据入队;还需要队列的数据区域

那么就需要用两个结构管理队列,一个是数据节点,一个队列

队列节点结构,专门管理数据的

typedef struct queueNode{

  int  data;   //数据域,存放的是有效数据

  struct queueNode  * next; //指向队列的下一个节点

}queueNode;

 

队列管理结构:

typedef struct linkqueue{

   struct queueNode  *front; // 指向队列头部 

   struct queueNode  *rear; // 指向队列尾部

}linkqueue;

1. front 只指向队列的头节点,通过头节点的next指针去访问数据节点,实现出对操作,

2. 链式队列没有满的情况,当队列为空时,头和尾都指向头节点(头节点只是用来管理这个链式对列,并不存放有效数据)

3. 队尾用来插入队列,对头用来出入操作

 

创建一个空的队列:

链表实现队列操作

 

插 入队列一个数据

 链表实现队列操作

这样通过队尾rear 一直指向链表的尾部管理的数据插入队列操作

 举例说明: 队列 linkqueue *qe;

(1) 插入一个新节点 queueNode *pnew 

(2)qe->rear->next 是当前节点的next指针,用来连接新节点的 qe->rear->next = pnew

(3)新节点的next指针指向空NULL , pnew->next = NULL;

(4)最后是把尾指针,移动指向尾部节点 qe->rear = qe->rear->next;

 linkqueue.c文件:

#include "linkqueue.h"

linkqueue *create_linkqueue(void)
{
    //创建队列
    linkqueue *qe=NULL;
    qe = (linkqueue*)malloc(sizeof(linkqueue));
    if(qe == NULL)
    {
        printf("create queue malloc error \n");
        return NULL;
    }

    //创建队列节点
    qe->front = (queueNode*)malloc(sizeof(queueNode));
    if(qe->front == NULL)
    {
        free(qe);
        printf("create node malloc error\n");
        return NULL;
    }
    qe->front->next = NULL;//队列头的next指向实际的数据节点
    qe->front->data = 0;
    qe->rear = qe->front; //队列空时,对头和对尾指向同一个位置
    return qe;
}

//插入数据,入队列,对尾入对
int in_linkqueue(linkqueue *qe, u16 value)
{
    if(qe == NULL)
    {
        printf("in lingkqueue is null\n");
        return -1;
    }
    queueNode *pnew = NULL;//入对的新节点
    pnew = (queueNode*)malloc(sizeof(queueNode));
    if(pnew == NULL)
    {
        printf("in pnew malloc is fail\n");
        return -1;
    }
    pnew->data = value;//入对的数据
    pnew->next = NULL;
    qe->rear->next = pnew;//把入对的节点链接到队列上
    qe->rear = qe->rear->next;//把指向对尾的指针,继续移动到队尾,即指向新插入的节点位置
    return 1;
}

//判断队列是否空,空返回1,非空返回0, 其他返回-1
int is_empty_linkqueue(linkqueue *qe)//判空
{
    if(qe == NULL)
    {
        printf("is empty lingkqueue is null\n");
        return -1;
    }
    return ((qe->front == qe->rear) ? 1 : 0);
}

int out_linkqueue(linkqueue *qe, u16 *dat)//出队列
{
    if(qe == NULL)
    {
        printf("out lingkqueue is null\n");
        return -1;
    }
    if(is_empty_linkqueue(qe) == 1)//队列为空
    {
        printf("out lingkqueue is empty\n");
        return 0;
    }
    queueNode *pdel = NULL;//出对的节点
    if(qe->front->next == NULL) //出对列,到对尾时
    {
        qe->rear = qe->front;
        return 0;
    }
    pdel = qe->front->next;//对头front永远头节点,出对时是头节点的下一个节点
    qe->front->next = pdel->next;//把要删除的节点的下一个节点地址链接到对列头上
    *dat = pdel->data; //对头的数据
    free(pdel);
    pdel = NULL;
    return 1; 
}

//显示队列内容,从对头开始显示
void show_linkqueue(linkqueue *qe)//显示队列内容
{
    if(qe == NULL)
    {
        printf("show lingkqueue is null\n");
        return;
    }
    if(is_empty_linkqueue(qe) == 1)//队列为空
    {
        printf("show lingkqueue is empty\n");
        return;
    }
    queueNode *pcur = qe->front->next;//找到数据节点开始
    while(pcur != NULL)
    {
        printf("%d\n",pcur->data);
        pcur = pcur->next;
    }
}

linkqueue.h文件:

#ifndef __LINKQUEUE_H
#define __LINKQUEUE_H

#include <stdio.h>
#include <stdlib.h>

typedef int u16;

//数据节点
typedef struct queueNode{
    u16 data;
    struct queueNode *next;
}queueNode;

//队列结构
typedef struct linkqueue{
    queueNode *front; //对列头节点
    queueNode *rear;  //队列尾节点
}linkqueue, *linkqueue_p;

linkqueue *create_linkqueue(void);
int in_linkqueue(linkqueue *qe, u16 value);//插入数据,入对列
int is_empty_linkqueue(linkqueue *qe);//判空
int out_linkqueue(linkqueue *qe, u16 *dat);//出队列
void show_linkqueue(linkqueue *qe);//显示队列内容

#endif

测试文件main.c:

#include "linkqueue.h"

int main(int argc, const char *argv[])
{
    linkqueue *s = NULL;

    s=create_linkqueue();
    in_linkqueue(s,1);
    show_linkqueue(s);

    putchar(10);

    in_linkqueue(s,2);
    in_linkqueue(s,3);
    in_linkqueue(s,4);
    in_linkqueue(s,5);
    show_linkqueue(s);

    putchar(10);
    int a=0;
    out_linkqueue(s,&a);
    printf("-------test------!\n");
    out_linkqueue(s,&a);
    show_linkqueue(s);


    return 0;
}

测试结果

链表实现队列操作