队列的链式存储结构的实现(八)

18.11.25

(基于C语言,欢迎指正)

链队列

队列的链式存储结构,其实就是线性表的单链表,只是它只能尾进头出而已,我们简称它为单链表,和队列的顺序存储结构一样,链队列也需要两个指向队首和队尾的指针frontrear,但是他们的指向稍微有点不同

下文描述中,队头等于队首,但不等于头结点

对于队列的顺序存储结构,front指向队头,rear指向队尾的下一个元素,像这样
(图丑了点-_-||)
在这里插入图片描述
对于链队列来说可不一样,front指向的是头结点(头结点不是队首,在队首前面,头结点没有数值),而rear指向队尾
像这样
在这里插入图片描述

然后就可以开始写这个程序了

准备工作

  1. 头文件
  2. 数据类型设定
  3. 结点设定
    (注意,链队列需要设定两个结构体,一个是结点的类型,一个是队列的结构体指针其中只包含front和rear要对整个链队列进行一些入队出队或者打印等操作时,都是传入队列的结构体指针,而不是只传一个结点)
#include<stdio.h>
#include<stdlib.h>

typedef int QElemType;//认为int 是QElemType

typedef struct QNode{     //队列结点定义
    QElemType data;       //包括一个数据域
    struct QNode *next;   //一个指针域,指向下一个结点
}QNode,*QueuePtr;

typedef struct{  //队列的结构体定义
    QueuePtr front,rear;
}LinkQueue;

初始化

一开始的时候,链队列中没有数值,front和rear都指向头结点

void InitQueue(LinkQueue *Q){//初始化
    QueuePtr H=(QueuePtr)malloc(sizeof(QNode));//给头结点分配内存
    if(!H){
        printf("内存分配失败");
        exit(1);
    }
    Q->front=H;        //front和rear都指向头结点
    Q->rear=H;
}

入队列

将新插入的元素插在队尾后面

void EnQueue(LinkQueue *Q,QElemType e){//入队列,传入头结点指针
    QueuePtr S=(QueuePtr)malloc(sizeof(QNode));//给插入的结点分配动态内存
    if(!S){
        exit(2);
    }
    S->next=NULL;//新结点的next指向空
    S->data=e;
    Q->rear->next=S;
    Q->rear=S;
}

出队列

首先要判断队列是否已经空了,即front和rear是不是指向头结点,空了就不能再出了

其次,如果将要出队列时,只剩下最后一个元素了,那么就要先将rear指针指向头结点,别搞丢了,在将出队列的结点内存释放掉

void DeQueue(LinkQueue *Q,QElemType *e){//出队列,并用*e存储出去的值
    if(Q->front==Q->rear){
        exit(3);
    }
    QueuePtr P;
    P=Q->front->next;
    *e=P->data;
    Q->front->next=P->next;
    if(Q->rear==P){   //只剩下最后一个元素了,那么就要先将rear指针指向头结点
        Q->rear=Q->front;
    }
    free(P);
}

打印

需要一个定位指针p,从队头一直走下去

void Print(LinkQueue *Q){//打印函数,队列空不打印
    if(Q->front==Q->rear){
        printf("链队列已空\n");
        exit(3);
    }
    QueuePtr p;
    p=Q->front->next;
    while(p){
        printf("%d  ",p->data);
        p=p->next;
    }
    printf("\n");
}

这样链队列的一些基本操作都写完了,我们在主函数中调试一下

源程序调试

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

typedef int QElemType;//认为int 是QElemType

typedef struct QNode{     //队列结点定义
    QElemType data;       //包括一个数据域
    struct QNode *next;   //一个指针域,指向下一个结点
}QNode,*QueuePtr;

typedef struct{  //队列的结构体定义
    QueuePtr front,rear;
}LinkQueue;

void InitQueue(LinkQueue *Q){//初始化
    QueuePtr H=(QueuePtr)malloc(sizeof(QNode));//给头结点分配内存
    if(!H){
        printf("内存分配失败");
        exit(1);
    }
    Q->front=H;        //front和rear都指向头结点
    Q->rear=H;
}

void EnQueue(LinkQueue *Q,QElemType e){//入队列,传入头结点指针
    QueuePtr S=(QueuePtr)malloc(sizeof(QNode));//给插入的结点分配动态内存
    if(!S){
        exit(2);
    }
    S->next=NULL;//新结点的next指向空
    S->data=e;
    Q->rear->next=S;
    Q->rear=S;
}

void DeQueue(LinkQueue *Q,QElemType *e){//出队列,并用*e存储出去的值
    if(Q->front==Q->rear){
        exit(3);
    }
    QueuePtr P;
    P=Q->front->next;
    *e=P->data;
    Q->front->next=P->next;
    if(Q->rear==P){   //只剩下最后一个元素了,那么就要先将rear指针指向头结点
        Q->rear=Q->front;
    }
    free(P);
}

void Print(LinkQueue *Q){//打印函数,队列空不打印
    if(Q->front==Q->rear){
        printf("链队列已空\n");
        exit(3);
    }
    QueuePtr p;
    p=Q->front->next;
    while(p){
        printf("%d  ",p->data);
        p=p->next;
    }
    printf("\n");
}

int main(){
    LinkQueue Q;
    InitQueue(&Q);
    int num,e,i;
    for(i=0;i<10;i++){
        EnQueue(&Q,i);
    }
    printf("此时链队列为:");
    Print(&Q);
    printf("输入要删除的结点的个数:");
    scanf("%d",&num);
    for(i=0;i<num;i++){
        printf("删除第%d个结点,此时链队列为:\n",i+1);
        DeQueue(&Q,&e);
        Print(&Q);
    }
    printf("\n最终队列为:\n");
    Print(&Q);
}

调试结果

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值