队列的链式存储结构及实现

ref : https://blog.csdn.net/qq_29542611/article/details/78907339



队列的链式存储结构,其实就是线性表的单链表,只不过它只是尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端节点。如果

空队列时,front和rear都指向头结点。

入队操作:

在队尾添加元素,先将队尾元素的next指向添加的元素,然后将队尾指针重新指向新的队尾即可。

出队操作:

头结结点指向的结点即为队头结点,出队操作,就是把队头结点干掉,先把头结点指向新的队头结点(也就是旧的队头结点的后继结点),然后释放旧的队头结点。如果链表除头结点外只剩一个元素时,则需将rear指向头结点即可

下面是队列链式存储结构实现的具体代码:

    #define _CRT_SECURE_NO_WARNINGS
    #include <stdio.h>
    #include <string.h>
    #include <math.h>
    #include <stdlib.h>
    #define QUEUESIZE 10
    #define ERROR 0
    #define OK 1
    #define TRUE 1
    #define FALSE 0
    #define EleType int
    #define Status int
    //链队列结点
    typedef struct QueueNode
    {
    EleType e;//数据域
    struct QueueNode* next;//指针域
    }QueueNode,*LinkQueuePoi;
    typedef struct LinkQueue
    {
    LinkQueuePoi front;//指向头结点
    LinkQueuePoi rear;//指向队尾
    }LinkQueue;
    /*
    初始化链队列
    链队列为空时,链队列队头指针队尾指针均指向头结点
    */
    Status InitLinkQueue(LinkQueue* queue)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));//头结点
    node->next = NULL;
    queue->front = queue->rear = node;
    return OK;
    }
    /*
    清空链队列
    将所有元素释放
    */
    Status CleaerLinkQueue(LinkQueue* queue)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    //空链队列
    if (queue->front == queue->rear)
    {
    return ERROR;
    }
    QueueNode* node = queue->front->next;//队头元素
    while (node)
    {

    queue->front->next = node->next;//指向新的队头结点
    if (queue->rear == node)//当删除的是队尾元素时,将队尾指针指向头结点
    {
    queue->rear = queue->front;
    }
    free(node);//释放旧的队头结点
    node = queue->front->next;
    }
    return OK;
    }
    /*
    判断链队列是否为空队列
    */
    Status EmptyLinkQueue(LinkQueue* queue)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    //空链队列
    if (queue->front == queue->rear)
    {
    return TRUE;
    }
    return FALSE;
    }
    /*
    获取链队列长度
    */
    int LengthLinkQueue(LinkQueue* queue)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    //空链队列
    if (queue->front == queue->rear)
    {
    return 0;
    }
    QueueNode* node = queue->front->next;
    int num = 0;
    while (node)
    {
    node = node->next;
    num++;
    }
    return num;
    }
    /*
    在链队列队尾添加元素
    先将新元素添加到链表尾部,然后将队列尾指针指向这个新元素
    */
    Status AddQueue(LinkQueue* queue,EleType e)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    QueueNode* node = (QueueNode*)malloc(sizeof(QueueNode));
    if (!node)
    {
    return ERROR;
    }
    node->next = NULL;
    node->e = e;
    queue->rear->next = node;//将新结点添加到链表表中
    queue->rear = node;//队尾指针指向新的队尾结点
    return OK;
    }
    /*
    从链队列中删除队头元素
    先将头结结点指向新的队头结点,然后释放原来的队头结点
    */
    Status DelQueue(LinkQueue* queue, EleType *e)
    {
    //空指针
    if (!queue)
    {
    return ERROR;
    }
    //注意queue->front是头结点,头结点指向的结点才是队头结点
    QueueNode* node = queue->front->next;//旧队头结点
    *e = node->e;
    queue->front->next = node->next;//队头指针指向新的队头结点
    //当删除的是队尾元素时,将队尾指针指向头结点
    if (node = queue->rear)
    {
    queue->rear = queue->front;
    }
    return OK;
    }
    /*
    打印链队列元素
    */
    void PrintfLinkQueue(LinkQueue* queue)
    {
    if (!queue)
    {
    return;
    }
    QueueNode* node = queue->front->next;
    while (node)
    {
    printf("%d,", node->e);
    node = node->next;
    }
    printf("\n");
    return;
    }
    int main(int argc, char *argv[])
    {
    LinkQueue queue;
    InitLinkQueue(&queue);
    AddQueue(&queue, 1);
    AddQueue(&queue, 2);
    AddQueue(&queue, 3);
    AddQueue(&queue, 4);
    AddQueue(&queue, 5);
    AddQueue(&queue, 6);
    AddQueue(&queue, 7);
    AddQueue(&queue, 8);
    AddQueue(&queue, 9);
    printf("链队列元素个数:%d\n",LengthLinkQueue(&queue));
    printf("展示元素:\n");
    PrintfLinkQueue(&queue);
    int e1, e2;
    DelQueue(&queue, &e1);
    DelQueue(&queue, &e2);
    printf("删除元素:%d,%d\n", e1, e2);
    printf("展示元素:\n");
    PrintfLinkQueue(&queue);
    printf("链队列元素个数:%d\n", LengthLinkQueue(&queue));
    CleaerLinkQueue(&queue);
    printf("清空元素后,长度为%d,rear = %p,front=%p",LengthLinkQueue(&queue), queue.rear,queue.front);
    printf("\n");
    return 0;
    }

验证结果截图:

对于循环队列与链队列的比较,可以从时间和空间2方面来考虑,从时间上,他们的基本操作都是常数时间,即都为O(1),不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则2者还是有些细微的差异。对于空间方面来说,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列就不存在这个问题,尽管它需要一些指针域,会产生一些空间上的开销,但也可以接受。所以在空间上,链队列更加灵活。

原文地址:https://www.cnblogs.com/schips/p/10631419.html

时间: 2024-10-14 00:42:57

队列的链式存储结构及实现的相关文章

数据结构:队列的链式存储结构

链队列的实现方法: 队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,简称为链队列.为了操作上的方便,我们将队头指针指向链队列的头节点,而队尾指针指向终端节点.空队列时,front和rear都指向头节点. 注意:这里的实现是有头结点的,在队列的初始化函数中要为头结点开辟空间. 链队列的实现代码: #include <iostream> #include <stdlib.h> using namespace std; /**********************

队列的链式存储结构(C语言实现)

1 #include <stdio.h> 2 #include <stdlib.h> 3 4 #define OK 1 5 #define ERR 2 6 #define TRUE 1 7 #define FALSE 0 8 9 typedef int status; //定义函数返回的状态,OK & ERR 10 typedef char datatype; //定义队列中每个元素的数据类型,这里暂定为字符型 11 12 typedef struct LinkQueue_

队列的链式存储结构

1 链队列的存储结构 将对头指针front指向链队列的头结点,队尾指针rear指向终端结点. 空队列时,头指针front和尾指针rear都指向头结点. 链队列的存储结构为: typedef int QElemType; typedef struct QNode { //结点结构 QElemType data; struct QNode *next; }QNode; typedef struct QNode * QueuePtr; typedef struct { //队列的链表结构 QueueP

队列的链式存储结构的实现2 —— 出队查看队首尾元素计算元素个数

// Filename : list_queue.c // Author : LupingChen // Data : 2015.05.30 // Content : create\destory\full\empty\push #include <stadio.h> #include <stdlib.h> //定义节点数据类型 typedef struct Node { int data;//节点数据 struct Node* next;//记录下一节点地址 } Node; //

(源代码见大话数据结构)线性表—队列的链式存储结构-&gt;出队&amp;入队&amp;建立空队列

#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define MAXSIZE 20 #define OVERFLOW 0 typedef int Status; typedef int QElemType; typedef struct QNode//标识符和类型名一样不知道什么用意.. { QElemType data; stru

队列的链式存储结构的实现1 —— 创建销毁判断满空入队

// Filename : list_queue.c // Author : LupingChen // Data : 2015.05.30 // Content : create\destory\full\empty\push #include <stadio.h> #include <stdlib.h> //定义节点数据类型 typedef struct Node { int data;//数据 struct Node* next;//记录下一节点地址 } Node; //定义

Java数据结构系列之——队列(3):队列的链式存储结构及其实现

package queue.linkQueue; public class Node { // 数据域 Object element; // 指针域 Node next; // 头结点初始化 public Node(Node next) { this.next = next; } // 非头结点初始化 public Node(Object element, Node next) { this.element = element; this.next = next; } } ***********

队列的链式存储结构的实现3——完结编

// Filename : list_queue.c // Authot : LupingChen // Data : 2014.06.01 // Content : main\clear #include <stdio.h> #include <stdlib.h> //定义节点数据类型 typedef struct Node { int data;//节点数据 struct Node* next;//记录下一节点地址 } Node; //定义队列数据类型 typedef stru

队列的顺序存储结构和链式存储结构

队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表(在队尾进行插入操作,在对头进行删除操作). 与栈相反,队列是一种先进先出(First In First Out, FIFO)的线性表. 与栈相同的是,队列也是一种重要的线性结构,实现一个队列同样需要顺序表或链表作为基础. 队列的链式存储结构 队列既可以用链表实现,也可以用顺序表实现.跟栈相反的是,栈一般我们用顺序表来实现,而队列我们常用链表来实现,简称为链队列. typedef struct QNode { ElemT