数据结构与算法 —— 队列的链式存储结构

一.概述

队列是一种只允许咋一端进行操作(插入,删除)的线性表,与栈相比,栈是一种先进后出(Fast In Last Out)的形式,队列则是先进先出(Fast In Fast Out),就像我们日常生活中的排队一样(大家都很有素质)。
在这里插入图片描述

二.结点定义

使用链式存储结构的方式,结点的定义:

typedef struct QNode {
    ElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct {
    QueuePtr front,rear; //队头,队尾指针
}LinkQueue;

为了方便操作,通常,会添加一个不用来存储数据的头结点:
在这里插入图片描述

二. 初始化队列

通过前面所说,创建一个队列,可以先创建一个头结点,再将我们定义好的头指针与尾指针指向头结点即可:

int InitQueue(LinkQueue *q)
{
    q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
    if(!q->front)
    {
        printf("Malloc failure\n");
        return -1;
    }

    q->front->next = NULL;
}

三. 入列

联想队列的存储结构,队列是从队尾插入,当有一个结点p想要进入队列,则需要下面的几个步骤:
在这里插入图片描述
代码:

void InsetQueue(LinkQueue *q,ElemType e)  //插入元素
{     
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));
      
    if(!p)
    { 
        printf("Malloc failure\n");
        exit(0);
    } 
      
    p->data = e;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
      
}     

四. 出列

获取到第一个结点的值,将头指针指向第二个结点:
在这里插入图片描述
需要注意两点,一是要先判断链表是否为空,二是判断出列一个元素后,链表是否为空:

void DeleteQueue(LinkQueue *q,ElemType *e)
{      
    if(q->front == q->rear)
    {  
        printf("链表当前为空\n");
        return;
    }  
       
    QueuePtr p;
    p = q->front->next;
    *e = p->data;
    q->front->next = p->next;  //指向第二个结点
   
    if(q->rear == p)
    {
        q->rear = q->front;
        printf("队列最后一个元素出列,队列成为空队列\n");
    }
    free(p);
   
}      

五. 销毁队列

如果队列过长将会占用极大一部风存储空间,在使用完时需要及时销毁从而释放内存,首先,将rear指针指向front->next,销毁front,再将front指向rear,rear再次指向front->next,直达最后都为NULL则结束:
在这里插入图片描述
代码:

void DestroyQueue(LinkQueue *q)
{  
    while(q->front)
    {
        q->rear = q->front->next;
        free(q->front);
        q->front = q->rear;
    }
    printf("链表已销毁\n");
}      

六. 运行程序

源码:

/*********************************************************************************
 *      Copyright:  (C) 2020 Xiao yang IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  Queue.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(06/20/2020)
 *         Author:  Lu Xiaoyang <[email protected]>
 *      ChangeLog:  1, Release initial version on "06/20/2020 09:06:49 AM"
 *                 
 ********************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

#define ElemType int

typedef struct QNode {
    ElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct {
    QueuePtr front,rear; //队头,队尾指针
}LinkQueue;

void InitQueue(LinkQueue *q)
{
    q->front = q->rear = (QueuePtr)malloc(sizeof(QNode));
    if(!q)
    {
        printf("Malloc failure\n");
        exit(0);
    }

    q->front->next = NULL;
}

void InsertQueue(LinkQueue *q,ElemType e)
{
    QueuePtr p;
    p = (QueuePtr)malloc(sizeof(QNode));

    if(!p)
    {
        printf("Malloc failure\n");
        exit(0);
    }

    p->data = e;
    p->next = NULL;
    q->rear->next = p;
    q->rear = p;
    
}

void DeleteQueue(LinkQueue *q,ElemType *e)
{
    if(q->front == q->rear)
    {
        printf("链表当前为空\n");
        return;
    }

    QueuePtr p;
    p = q->front->next;
    *e = p->data;
    q->front->next = p->next;  //指向第二个结点

    if(q->rear == p)
    {
        q->rear = q->front;
        printf("队列最后一个元素出列,队列成为空队列\n");
    }
    free(p);
}

void DestroyQueue(LinkQueue *q)
{
    while(q->front)
    {
        q->rear = q->front->next;
        free(q->front);
        q->front = q->rear;
    }
    printf("链表已销毁\n");
}

int main(int argc, char *argv[])
{
    int i = 0;
    int temp;

    LinkQueue Que;
    InitQueue(&Que);

    for(i = 1; i <=10; i++)
    {
        InsertQueue(&Que,i);
    }

    for(i = 1; i<= 10; i++)
    {
        DeleteQueue(&Que,&temp);
        printf("获取到链表元素%d \n",temp);
    }

    DestroyQueue(&Que);

    return 0;
}

运行结果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45121946/article/details/106867537