栈与队列(五)链队列(链式结构)

本文介绍了链队列的基本概念及其实现方法,包括初始化、入队、出队和销毁等核心操作,并通过一个简单的字符输入输出实例展示了链队列的应用。

队列(以链式为主)

定义:是只允许在一端进行插入操作,而在另一端进行删除操作的线性表
与栈(后进先出)不同,队列是先进先出
队头(删除的一端)(指头结点):出队列
队尾(插入的一端)(指an):入队列


例子:输入的缓冲区就是按照队列
比如输入god   先进先出(输出),如果按照栈的思想就是输出为dog了。


队列的链式存储结构(栈一般是顺序,而队列是链式)简称,链队列

typedef int ElemType;//类型视情况而定

typedef struct QNode//结点结构,结点
{
    ElemType data;//数据域
    struct QNode *next;//指向下一个数据,指针域
}QNode,*QueuePtr;//结构体变量和结构体指针

typedef struct    
{
    QueuePtr front;//队头指针
    QueuePtr rear;//队尾指针
}LinkQueue;


将队头指针指向链队列的头结点,队尾指针指向终端结点(an).(注:头结点不是必要的,但为了方便,我们加上。)
front指向头结点,下一个是a1,rear指向终端结点an。
当为空队列时front和rear都指向头结点


一、创建一个队列
两个任务:(1).在内存中创建一个头结点   (2).将队列的头指针和尾指针都指向这个生成的头结点,此时为空队列(一个初始化阶段)

void initQueue(LinkQueue *q)//q为结构体指针,初始化
{
     q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));//用malloc动态生成头结点,然后队头队尾指针指向这个头结点
     if(!q->front)
        exit(0);
     q->front->next=NULL;//空队列
}



二、入队列操作
void InserQueue(LinkQueue *q,ElemType e)
{
     QueuePtr p;
     p=(QueuePtr)malloc(sizeof(QNode));//申请一个p结点
     if(p==NULL)
       exit(0);
     p-data=e;//p的数据域为要插入的值e
     p->next=NULL;//p的指针域next的下一个为NULL
     q->rear->next=p;//本来q->rear->next为NULL,现在将p赋值给它,先连接起来
     q->rear=p;//最后直接将p结点赋值给q,p就不要了,可以扔了
}



三、出队列操作
将队列中的第一个元素移除,队头指针不发生改变,改变头结点的next指针即可
就是直接将头结点next指向下一个元素
如果原队列只有一个元素,那么我们应该处理一下队尾指针
void DeleteQueue(LinkQueue *q,ElemType *e)
{
     QueuePtr p;
     if(q->front==q->rear)//空队列
         return;
     p=q->front->next;//将欲删除的队头结点暂存给p
     *e=p->data;//将欲删除的队头结点的值赋值给e    
     q->front->next=p->next;//将原队头接待的后继p->next赋值给头结点后继
     if(q->rear==p)//意思为队列中只有一个元素,即处理队尾指针,q->rear指向头结点
       q->rear=q->front;
     free(p);
} 

  

四、销毁一个队列
由于链队列建立再内存的动态区,因此当一个队列不再有用时应当把它及时销毁,以免过多占内存

void DestroyQueue(LinkQueue *q)
{
     while(q->front){
       q->rear=q->front->next;
       free(q->front);
       q->front=q->rear;
    }
}


五、实例:输入一组字符然后打印出来

/*************************************************************************
    > File Name: 链队列.c
    > Author: geeker
    > Mail: 932834897@qq.com
    > Created Time: 2017年02月11日 星期六 12时50分07秒
 ************************************************************************/

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef char ElemType;

typedef struct QNode
{
    ElemType data;
    struct QNode *next;
}QNode,*QueuePtr;

typedef struct
{
    QueuePtr front;
    QueuePtr rear;
}LinkQueue;

void initQueue(LinkQueue *q)//初始化
{
    q->front=q->rear=(QueuePtr)malloc(sizeof(QNode));
    if(!q->front)
        exit(0);
    q->front->next=NULL;
}

void InsertQueue(LinkQueue *q,ElemType e)//入队列
{
    QueuePtr p;
    p=(QueuePtr)malloc(sizeof(QNode));
    if(p==NULL)
        exit(0);
    p->data=e;
    p->next=NULL;
    q->rear->next=p;
    q->rear=p;
}

void DeleteQueue(LinkQueue *q,ElemType *e)//出队列
{
    QueuePtr p;
    if(q->front==q->rear)
        return;
    p=q->front->next;
    *e=p->data;
    q->front->next=p->next;
    if(q->rear==p)
        q->rear=q->front;
    free(p);
}

void DestroyQueue(LinkQueue *q)//销毁一个队列
{
    while(q->front){
        q->rear=q->front->next;
        free(q->front);
        q->front=q->rear;
    }
}

int main()
{
    ElemType c;
    LinkQueue s;

    initQueue(&s);
    printf("请输入一个字符串,并#为结束输入:\n");
    scanf("%c",&c);

    while(c!='#')
    {
        InsertQueue(&s,c);
        scanf("%c",&c);
    }
    printf("打印队列中的元素");
        while(s.front!=s.rear)//注意这里不是指值,而是指位置
        {
            DeleteQueue(&s,&c);
            printf("%c",c);
        }
    DestroyQueue(&s);
    return 0;
}

//abcdefg#
//输出:abcdefg



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值