【笔记】链式队列

本文介绍了链式队列的基本概念,包括链式队列和链式循环队列的表示方式,以及如何通过链表实现队列的操作。进一步探讨了如何利用链式队列来判断一个字符序列是否为回文。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、链式队列的表示

1.链式队列

  用链表表示的队列,简称为链队列。链式队列在插入和删除过程中不需要移动大量的元素,只需要改变指针的位置即可。
  一个链式队列显然需要两个分别指示队头和队尾的指针(分别称为头指针和尾指针)才能唯一确定。空的链队列的判决条件为头指针和尾指针均指向头结点。


这里写图片描述

2.链式循环队列

  将链式队列的首尾相连就构成了链式循环队列。在链式循环队列中,可以只设置队尾指针。当队列为空时,判断条件为LQ.rear->next==LQ.rear。


这里写图片描述


二、链式队列的实现

  题目:判断任意给定的字符序列是否为回文。
  分析:可以通过构造栈和队列实现。可先把一个字符序列分别存入队列和栈,然后将字符出队列和出栈,比较出队列的字符和出栈的字符是否相等,若相等则继续出队列和栈中的下一个字符进行比较,直到栈和队列为空,表明该字符序列为回文;若有字符不相等,则该字符序列不是回文。

  • 类型定义
#include<stdio.h>       
#include<stdlib.h>      
#include<string.h>      
#include<malloc.h>      
typedef char DataType;  /*数据类型为字符类型*/
/*链式堆栈结点类型定义*/
typedef struct snode
{
    DataType data;
    struct snode *next;
}LSNode;
/*只有队尾指针的链式循环队列类型定义*/
typedef struct QNode
{
    DataType data;
    struct QNode *next;
}LQNode,*LinkQueue;
  • 栈的函数
void InitStack(LSNode **head)
/*带头结点的链式堆栈初始化*/
{
    if((*head=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*为头结点分配空间*/
    {
        printf("分配结点不成功");
        exit(-1);
    }
    else
        (*head)->next=NULL;         /*头结点的指针域设置为空*/
}
int StackEmpty(LSNode *head)
/*判断带头结点链式堆栈是否为空。如果堆栈为空,返回1,否则返回0*/
{
    if(head->next==NULL)    /*如果堆栈为空,返回1,否则返回0*/
        return 1;
    else
        return 0;
}
int PushStack(LSNode *head,DataType e)
/*链式堆栈进栈。进栈成功返回1,否则退出*/
{
    LSNode *s;
    if((s=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*为结点分配空间,失败退出程序并返回-1*/
        exit(-1);
    else
    {
        s->data=e;              /*把元素值赋值给结点的数据域*/
        s->next=head->next;     /*将结点插入到栈顶*/
        head->next=s;
        return 1;
    }
}
int PopStack(LSNode *head,DataType *e)
/*链式堆栈出栈,需要判断堆栈是否为空。出栈成功返回1,否则返回0*/
{
    LSNode *s=head->next;       /*指针s指向栈顶结点*/
    if(StackEmpty(head))        /*判断堆栈是否为空*/
        return 0;
    else
    {
        head->next=s->next;     /*头结点的指针指向第二个结点位置*/
        *e=s->data;             /*要出栈的结点元素赋值给e*/
        free(s);                /*释放要出栈的结点空间*/
        return 1;   
    }
}
  • 初始化队列
void InitStack(LSNode **head)
/*带头结点的链式堆栈初始化*/
{
    if((*head=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*为头结点分配空间*/
    {
        printf("分配结点不成功");
        exit(-1);
    }
    else
        (*head)->next=NULL;         /*头结点的指针域设置为空*/
}
  • 获取队列状态
void InitQueue(LinkQueue *rear)   
/*将带头结点的链式循环队列初始化为空队列,需要把头结点的指针指向头结点*/
{
    if((*rear=(LQNode*)malloc(sizeof(LQNode)))==NULL)
        exit(-1);                   /*如果申请结点空间失败退出*/
    else
        (*rear)->next=*rear;        /*队尾指针指向头结点*/
}

int QueueEmpty(LinkQueue rear)    
/*判断链式队列是否为空,队列为空返回1,否则返回0*/
{
    if(rear->next==rear)        /*判断队列是否为空。当队列为空时,返回1,否则返回0*/
        return 1;
    else
        return 0;
}
  • 入队操作
int EnQueue(LinkQueue *rear,DataType e)
/*将元素e插入到链式队列中,插入成功返回1*/
{
    LQNode *s;
    s=(LQNode*)malloc(sizeof(LQNode));  /*为将要入队的元素申请一个结点的空间*/
    if(!s) exit(-1);                    /*如果申请空间失败,则退出并返回参数-1*/
    s->data=e;                          /*将元素值赋值给结点的数据域*/
    s->next=(*rear)->next;              /*将新结点插入链式队列*/
    (*rear)->next=s;
    *rear=s;                            /*修改队尾指针*/
    return 1;
}
  • 出队操作
int DeQueue(LinkQueue *rear,DataType *e)
/*删除链式队列中的队头元素,并将该元素赋值给e,删除成功返回1,否则返回0*/
{
    LQNode *f,*p;
    if(*rear==(*rear)->next)    /*在删除队头元素即出队列之前,判断链式队列是否为空*/
        return 0;
    else
    {
        f=(*rear)->next;        /*使指针f指向头结点*/
        p=f->next;              /*使指针p指向要删除的结点*/    
        if(p==*rear)            /*处理队列中只有一个结点的情况*/
        {
            *rear=(*rear)->next;/*使指针rear指向头结点*/
            (*rear)->next=*rear;
        }
        else
            f->next=p->next;    /*使头结点指向要出队列的下一个结点*/
        *e=p->data;             /*把队头元素值赋值给e*/
        free(p);                /*释放指针p指向的结点*/
        return 1;
    }
}
  • 主程序
int DeQueue(LinkQueue *rear,DataType *e)
/*删除链式队列中的队头元素,并将该元素赋值给e,删除成功返回1,否则返回0*/
{
    LQNode *f,*p;
    if(*rear==(*rear)->next)    /*在删除队头元素即出队列之前,判断链式队列是否为空*/
        return 0;
    else
    {
        f=(*rear)->next;        /*使指针f指向头结点*/
        p=f->next;              /*使指针p指向要删除的结点*/    
        if(p==*rear)            /*处理队列中只有一个结点的情况*/
        {
            *rear=(*rear)->next;/*使指针rear指向头结点*/
            (*rear)->next=*rear;
        }
        else
            f->next=p->next;    /*使头结点指向要出队列的下一个结点*/
        *e=p->data;             /*把队头元素值赋值给e*/
        free(p);                /*释放指针p指向的结点*/
        return 1;
    }
}
  • 测试结果


这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值