链队列的综合操作(详解、演示)C语言实现

队列的简介

和栈相反,队列(queue)是一种先进先出(简称FIFO)的线性表。它只允许在表的一端进行插入,而在另一端删除元素。

举个我们生活中最最常见的例子:银行排队(不管什么排队),当我们去银行办理业务的时候,我们要按照先来后到的规矩,先来的人先处理后面的人候着,先来的人处理完了之后先走…..
根据上面的例子大家应该可以很清楚的理解队列是什么了,再来看个示意图

这里写图片描述

和线性表类似,队列也有两种存储表示
用链表表示的队列称为链队列、还有一个循环队列在下一篇博客讲。一个链队列显然需要两个分别指向队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。这里,和线性表的单链表一样,为了操作方便起见,我们也给链队列添加一个头结点,并令头结点指针指向头结点,由此。空的链队列的判决条件为头指针和尾指针均指向头结点。
链队列的操作即是单链表的插入和删除操作的特殊情况。只需修改头尾指针即可,下面的程序实现和演示了,队列的构造、销毁、清空队列、销毁队列、判断队列是否为空、获得队列长度、获得队头、入队列、出队列、显示队列等功能。

/*********************************************************
-  Copyright (C): 2016
-  File name    : queue.c
-  Author       : - Zhaoxinan -
-  Date         : 2016年04月21日 星期四 15时34分59秒
-  Description  : 单链队列的存储

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

#define TRUE      1
#define FALSE    -1
#define OK        1
#define ERROR    -1
#define OVERFLOW -2

/* ----     单链队列----队列的链式存储结构   ---- */
typedef struct Qnode
{
    int date;
    struct Qnode *next;
}QNode,* QueuePtr;

typedef struct
{
    QueuePtr head;    //队头指针
    QueuePtr tail;    //队尾指针
}LinkQueue; 

/* ---- 基本操作函数 ---- */
/* ---- 构造一个空队列 ---- */

int InitQueue(LinkQueue *Q)
{
    Q->head = Q->tail = (QueuePtr)malloc(sizeof(QNode));
    if (Q->head == NULL)
    {
        exit(OVERFLOW);
    }
    Q->tail->next = NULL;
    return OK;
}

/* ---- 销毁队列Q,Q不再存在 ---- */
int DestoryQueue(LinkQueue *Q)
{
    //head->node1->node2->node3->tail;
    //             tail
    //       head->node2       
    while(Q->head)
    {
        Q->tail = Q->head->next;
        free(Q->head);
        Q->head = Q->tail;
    }
    Q->head = Q->tail = NULL;
    return OK;

}

/* ---- 将Q清空空队列 ---- */
int ClearQueue(LinkQueue *Q)
{
     QueuePtr temp;
     Q->tail = Q->head->next;
     while(Q->tail)
     {
         temp = Q->tail->next; //指向下一个待释放的单元
         free(Q->tail);
         Q->tail = temp;
     }
     Q->tail = Q->head; //修改队尾指针
     return OK;
}

/* ---- 若队列Q为空队列,返回TRUE,否则返回FALSE ---- */
int QueueEmpty(LinkQueue Q)
{
    if (Q.head == Q.tail && Q.head != NULL)
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
}

/* ---- 返回Q的元素个数,即队列的长度 ---- */
int QueueLength(LinkQueue Q)
{
    if (Q.head == NULL)
    {
        return 0;
    }
    QueuePtr temp;
    int count = 0;
    temp = Q.head->next;
    while(temp != NULL)
    {
        temp = temp->next;
        ++count;
    }
    return count;
}

/* ---- 显示当前队列的值从队头到队尾 ---- */
void show_queue(LinkQueue Q)
{
    QueuePtr temp;
    temp = Q.head->next;
    printf("  当前队列从头到尾:");
    while(temp != NULL)
    {
        printf("%d  ", temp->date);
        temp = temp->next;
    }
    printf("\n");
}


/* ---- 若队列不空,则用e返回Q的队头元素,并返回OK, 否则返回ERROR ---- */
int GetHead(LinkQueue Q, int *e)
{
    if (QueueEmpty(Q) == TRUE)
    {
        return ERROR;
    }

    *e = Q.head->next->date;
    return  OK;

}

/* ---- 插入元素e为Q的新的对尾元素 ---- */
int EnQueue(LinkQueue *Q, int e)
{
    if (Q->head == NULL || Q->tail == NULL)
    {
        return ERROR;
    }
    QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode));
    if (!ptr)
    {
        exit(OVERFLOW);
    }
    ptr->date = e;
    ptr->next = NULL;

    Q->tail->next = ptr;
    Q->tail = ptr;
    return OK;
}

/* ---- 若队列不空,则删除Q的队头元素,并用e返回其值,并返回OK,否则返回ERROR ---- */
int DeQueue(LinkQueue *Q, int *e)
{
    if (Q->head == Q->tail)
    {
        return ERROR;
    }
    /* ptr为临时变量 */
    QueuePtr ptr = (QueuePtr)malloc(sizeof(QNode));
    //head->node1->node2->tail;
    //       ptr
    //      head->node2->tail

    ptr = Q->head->next;
    *e = ptr->date;
    Q->head->next = ptr->next;
    if (Q->tail == ptr)
    {
        Q->head = Q->tail;
    }
    free(ptr);
    return OK;
}

int main()
{
    int i;        //循环变量
    int count;    //计数变量
    int outque;   //出队元素值
    LinkQueue Q;

    /* 初始化队列 */
    InitQueue(&Q);

    /* 插入10个元素 */
    printf("________________入队10个元素________________\n\n");
    for (i = 0; i < 10; i++)
    {
        /* 入队 */
        EnQueue(&Q, i);
        /* 获得当前队列中元素个数 */
        count = QueueLength(Q);
        printf("%2d 入队_当前队列中元素个数:%2d",i, count);
        show_queue(Q);
    }

    printf("________________出队5个元素________________\n\n");
    for (i = 0; i < 5; i++)
    {
        /* 出队 */
        DeQueue(&Q, &outque);
        /* 获得当前队列中元素个数 */
        count = QueueLength(Q);
        printf("%2d 出队_当前队列中元素个数:%2d", outque, count);
        show_queue(Q);
    }
    /* 获得当前队头值 */
    GetHead(Q, &outque);
    printf("\n当前队头为:%d\n", outque);

    printf("________________清空队列_________________\n\n");
    ClearQueue(&Q);

    count = QueueLength(Q);
    printf("当前队列中元素个数:%2d", count);
    show_queue(Q);

    printf("________________销毁队列_________________\n\n");
    DestoryQueue(&Q);
    count = QueueLength(Q);
    printf("当前队列中元素个数:%2d\n\n", count);

    return 0;
}

程序的运行结果

这里写图片描述

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxnsirius

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值