队列(以链式为主)
定义:是只允许在一端进行插入操作,而在另一端进行删除操作的线性表
与栈(后进先出)不同,队列是先进先出
队头(删除的一端)(指头结点):出队列
队尾(插入的一端)(指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
本文介绍了链队列的基本概念及其实现方法,包括初始化、入队、出队和销毁等核心操作,并通过一个简单的字符输入输出实例展示了链队列的应用。
2725

被折叠的 条评论
为什么被折叠?



