队列的链式存储实现


队列的链式存储实现

链式队列 : 用链表形式实现的队列。链表结点为队列数据存储区,链表结点包括两部分数据存储

区和指针存储区。

数据存储区 :存放真实有效数据的区域。

指针存储区 :存放下一个链表结点的地址。

二、实现过程

1.链式队列概念图(有头结点):

在这里插入图片描述

2.链式队列结构体:

头指针执行头结点,尾指针指向尾结点

//线性表存储结构
typedef struct LNode
{
        ElemType data;                  //存储队列中的元素。
        struct LNode* next;             //next指针

}LNode;

//队列的指针头和尾
typedef struct
{
  LNode *front,*rear;     // 队列的头指针和尾指针。
}LinkQueue,*PLinkQueue;

3.队列的基本操作

在这里插入图片描述

4.代码实现:

/*
        程序名:linkqueue.cpp 此程序演示队列的链表实现(带头结点)。
*/


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

typedef int ElemType;                   //自定义队列的数据元素为整数。

//线性表存储结构
typedef struct LNode
{
        ElemType data;                  //存储队列中的元素。
        struct LNode* next;             //next指针

}LNode;

//队列的指针头和尾
typedef struct
{
  LNode *front,*rear;     // 队列的头指针和尾指针。
}LinkQueue,*PLinkQueue;


//队列QQ的初始化操作。
int InitQueue(PLinkQueue QQ);

// 销毁队列QQ。
void DestroyQueue(PLinkQueue QQ);

// 清空队列。
void Clear(PLinkQueue QQ);

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PLinkQueue QQ, ElemType *ee);

// 打印队列中全部的元素。
void PrintQueue(PLinkQueue QQ);

// 求队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PLinkQueue QQ);

// 判断队列是否已满,链式队列不存在队满的说法。
int IsFull(PLinkQueue QQ);

// 判断队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PLinkQueue QQ);

// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PLinkQueue QQ, ElemType *ee);

// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PLinkQueue QQ, ElemType *ee);


int main()
{
        LinkQueue QQ;     // 创建队列。

        memset(&QQ,0,sizeof(LinkQueue));

        InitQueue(&QQ);  // 初始化队列。

        ElemType ee;     // 创建一个数据元素。

        printf("元素(1、2、3、4、5、6、7、8、9、10)入队。\n");
        ee=1;  InQueue(&QQ, &ee);
        ee=2;  InQueue(&QQ, &ee);
        ee=3;  InQueue(&QQ, &ee);
        ee=4;  InQueue(&QQ, &ee);
        ee=5;  InQueue(&QQ, &ee);
        ee=6;  InQueue(&QQ, &ee);
        ee=7;  InQueue(&QQ, &ee);
        ee=8;  InQueue(&QQ, &ee);
        ee=9;  InQueue(&QQ, &ee);
        ee=10; InQueue(&QQ, &ee);

        printf("队列的长度是%d\n",Length(&QQ));

        printf("打印队列元素:\n");
        PrintQueue(&QQ);

        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);
        if (OutQueue(&QQ,&ee)==1)  printf("出队的元素值为%d\n",ee);

        printf("队列的长度是%d\n",Length(&QQ));
        PrintQueue(&QQ);

        printf("元素(11、12、13、14、15)入队。\n");
        ee=11;  InQueue(&QQ, &ee);
        ee=12;  InQueue(&QQ, &ee);
        ee=13;  InQueue(&QQ, &ee);
        ee=14;  InQueue(&QQ, &ee);
        ee=15;  InQueue(&QQ, &ee);

        printf("队列的长度是%d\n",Length(&QQ));


        PrintQueue(&QQ);
        // 只查看队头元素的值,元素不出队。
        if (GetHead(&QQ,&ee)==1)  printf("队头的元素值为%d\n",ee);


//      printf("清除前front=%p,rear=%p\n",QQ.front,QQ.rear);
        Clear(&QQ); // 销毁队列QQ。     
//      printf("清除后front=%p,rear=%p\n",QQ.front,QQ.rear);

//      printf("销毁前front=%p,rear=%p\n",QQ.front,QQ.rear);
        DestroyQueue(&QQ); // 销毁队列QQ。      
//      printf("销毁后front=%p,rear=%p\n",QQ.front,QQ.rear);
        return 0;
}

//队列QQ的初始化操作。
int InitQueue(PLinkQueue QQ)
{
        if(QQ == NULL){ printf("队列不存在\n"); return 0; }

        //创建头结点
        LNode* head=(LNode*)malloc(sizeof(LNode));
        if(head==NULL){ printf("内存不足,分配结点失败。\n");return 0; }

        head->next=NULL;

        QQ->front=QQ->rear=head;
        return 1;
}

// 销毁队列QQ。删除所有结点
void DestroyQueue(PLinkQueue QQ)
{
        //队列指针不存在 
        if(QQ==NULL){ printf("队列不存在\n"); return ; }

        // 未初始化 即头尾指针没有指向头结点
        if(QQ->front==NULL){
                printf("队列未初始化。\n");
                return ;
        }


        LNode* tmp=QQ->front;

        //逐个结点删除
        while(tmp != QQ->rear->next)
        {
                tmp=tmp->next;          //下个结点地址
                free(QQ->front);        //释放本结点地址
                QQ->front=tmp;          //指针指向下一个结点
        }

        QQ->front=QQ->rear=NULL;
        return ;
}

// 清空队列。删除了除头结点以外的所有结点
void Clear(PLinkQueue QQ)
{

        //队列指针不存在 
        if(QQ==NULL){ printf("队列不存在\n"); return ; }

        // 未初始化 即头尾指针没有指向头结点
        if(QQ->front==NULL){
                printf("队列未初始化。\n");
                return ;
        }

        LNode *head=QQ->front;          //保存头结点

        LNode* tmp=QQ->front->next;     //从首节点开始删除

        //逐个结点删除
        while(tmp != QQ->rear->next)
        {
                tmp=tmp->next;          //下个结点地址
                free(QQ->front);        //释放本结点地址
                QQ->front=tmp;          //指针指向下一个结点
        }

        QQ->front=QQ->rear=head;
        QQ->front->next=QQ->rear->next=NULL;
}

// 元素入队,返回值:0-失败;1-成功。
int InQueue(PLinkQueue QQ, ElemType *ee)
{
        //队列指针不存在
        if(QQ==NULL){ printf("队列不存在\n"); return 0; }

        //未初始化 即头尾指针没有指向头结点
        if(QQ->front==NULL){
                printf("队列未初始化。\n");
                return 0;
        }

        //新建一个结点
        LNode *newnode=(LNode*)malloc(sizeof(LNode));
        if(newnode==NULL)return 0;
        //将元素值赋值给新结点
        memcpy(&newnode->data,ee,sizeof(ElemType));


        newnode->next=NULL;
        QQ->rear->next=newnode;
        QQ->rear=newnode;

        return 1;
}

// 打印队列中全部的元素。
void PrintQueue(PLinkQueue QQ)
{
        //队列指针不存在
        if(QQ==NULL){ printf("队列不存在\n"); return ; }

        //未初始化 即头尾指针没有指向头结点
        if(QQ->front==NULL){
                printf("队列未初始化。\n");
                return ;
        }


        LNode* tmp=QQ->front->next;             //从首节点开始输出


        //当指针没查询到尾指针的next域,一直查询
        while(tmp!=QQ->rear->next){
                printf("%3d ",tmp->data);
                tmp=tmp->next;
        }

        printf("\n");
}

// 求队列的长度,返回值:>=0-队列QQ元素的个数。
int  Length(PLinkQueue QQ)
{
        //队列指针不存在
            if(QQ==NULL){ printf("队列不存在\n"); return 0; }

        //未初始化 即头尾指针没有指向头结点
        if(QQ->front==NULL){
                printf("队列未初始化。\n");
                return 0;
        }

        LNode* tmp=QQ->front->next;     //从首节点开始计数
        if(tmp==NULL)return 0;

        int length=1;                   //头结点序号为1 

        while(tmp!=QQ->rear)
        {
                length++;
                tmp=tmp->next;
        }

        return length;
}

// 判断队列是否已满,链式队列不存在队满的说法。
int IsFull(PLinkQueue QQ)
{
        //队列指针不存在
        if(QQ==NULL){ printf("队列不存在\n"); return 0; }
        return 1;
}

// 判断队列是否为空,返回值:1-空,0-非空或失败。
int  IsEmpty(PLinkQueue QQ)
{
        //队列指针不存在
        if(QQ==NULL){ printf("队列不存在\n"); return 0; }

        //首尾相等为空
        if(QQ->front==QQ->rear)return 1;
        return 0;

}
// 元素出队,返回值:0-失败;1-成功。
int OutQueue(PLinkQueue QQ, ElemType *ee)
{
        //队列指针不存在
        if(QQ==NULL){ printf("队列不存在\n"); return 0; }

        if(QQ->front==NULL){printf("队列未初始化");return 0;}

        if(IsEmpty(QQ)){ printf("队空,无元素可以出队。\n"); return 0; }          
        //队头元素出队
        LNode* tmp=QQ->front->next;

        //队尾
        memcpy(ee,&tmp->data,sizeof(ElemType));

        QQ->front->next=tmp->next;

        // 如果出队的是最后一个结点。
        if (QQ->rear==tmp) QQ->rear=QQ->front;
        free(tmp);

        return 1;
}
// 获取队头元素,返回值:0-失败;1-成功。
// 只查看队头元素的值,元素不出队。
int GetHead(PLinkQueue QQ, ElemType *ee)
{
        if(QQ==NULL){ printf("队列不存在\n"); return 0; }

        if(QQ->front==NULL){printf("队列未初始化");return 0;}

        if(IsEmpty(QQ)){ printf("队空,无元素可以出队。\n"); return 0; }

        //取队头元素
        memcpy(ee,&QQ->front->next->data,sizeof(ElemType));

        return 1;
}         
                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值