一、定义
队列简称队,它是一种操作受限的线性表,其限制为仅允许在表的一端进行插入操作,而在表的另一端进行删除操作。把进行插入的一端称为队尾,把进行删除的一端称为队头或队首。向队列中插入新元素称为进队或入队,从队列中删除元素称为出队或离队。由于队列的插入和删除操作分别是在各自的一端进行的,每个元素必然按照进入的次序出队,所以又把队列称为先进先出表。
采用顺序存储结构的队列称为顺序队
声明顺序队
typedef struct
{
ElemType data[MaxSize]; //存放队中元素
int front,rear; //队首和队尾指针
} SqQueue;
采用链式存储结构的队列称为链队
声明链队
typedef struct DataNode
{
ElemType data;
struct DataNode *next;
} DataNode; //链队数据结点类型
typedef struct
{
DataNode *front;
DataNode *rear;
} LinkQuNode; //链队类型
二、基本运算
顺序队
设计顺序队基本运算算法四要素:
1.队空的条件:q->front ==q->rear;
2.队满的条件:q->rear ==MaxSize-1(data数组的最大下标);
3.元素e进队操作:先将rear加1,然后将元素e放在data数组的rear位置;
4元素出队操作:先将front加1,然后取出data数组front位置的元素。
初始化队列
void InitQueue(SqQueue *&q)
{
q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=q->rear=-1;
}
构造一个空队列q,将front和rear指针均设置为初始值-1。
本算法的时间复杂度为O(1)
销毁队列
void DestroyQueue(SqQueue *&q)
{
free(q);//销毁队列
}
释放队列q占用的空间
本算法的时间复杂度为O(1)
判断队列是否为空
bool QueueEmpty(SqQueue *q) //判断队列是否为空
{
return(q->front==q->rear);
}
队列为空返回true,否则返回false。
本算法的时间复杂度为O(1)
进队列
bool enQueue(SqQueue *&q,ElemType e) //进队
{
if (q->rear==MaxSize-1) //队满上溢出
return false; //返回假
q->rear++; //队尾增1
q->data[q->rear]=e; //rear位置插入元素e
return true; //返回真
}
先判断队列是否为满,如果为满则返回false,否则先将rear加1,然后将元素e放到该位置,最后返回true。
本算法的时间复杂度为O(1)
出队列
bool deQueue(SqQueue *&q,ElemType &e) //出队
{
if (q->front==q->rear) //队空下溢出
return false;
q->front++;
e=q->data[q->front];
return true;
}
先判断队列是否为空,如果为空则返回false,否则先将队头指针加1,然后将该位置元素的值赋给e,最后返回true。
本算法的时间复杂度为O(1)
链队
设计链队基本运算算法四要素:
1.队空的条件:q->front ==NULL(或q->rear ==NULL);
2.队满的条件:不存在;
3.元素e进队操作:新建一个结点存放元素e(由p指向它),将结点p插入作为尾结点;
4元素出队操作:取出队首结点的data值并将其删除。
初始化队列
void InitQueue(LinkQuNode *&q)
{
q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
q->front=q->rear=NULL; //将front和rear置为NULL
}
构造一个空队列(即创建一个链队结点),将front和rear置为NULL。
本算法的时间复杂度为O(1)
销毁队列
void DestroyQueue(LinkQuNode *&q)
{
DataNode *p=q->front,*r;//p指向队头数据结点
if (p!=NULL) //释放数据结点占用空间
{
r=p->next;
while (r!=NULL)
{
free(p);
p=r;r=p->next;
}
}
free(p);
free(q); //释放链队结点占用空间
}
从q->front结点开始,依次释放各结点内存。
本算法的时间复杂度为O(n)
判断队列是否为空
bool QueueEmpty(LinkQuNode *q)
{
return(q->rear==NULL);
}
q->rear=0时,队列为空,判断q->rear是否为0即可。
本算法的时间复杂度为O(1)
进队列
void enQueue(LinkQuNode *&q,ElemType e)
{
DataNode *p;
p=(DataNode *)malloc(sizeof(DataNode));
p->data=e;
p->next=NULL;
if (q->rear==NULL) //若链队为空,则新结点是队首结点又是队尾结点
q->front=q->rear=p;
else
{
q->rear->next=p; //将p结点链到队尾,并将rear指向它
q->rear=p;
}
}
创建一个新结点(由p指向它)存放元素e的值。如果队列为空,则将链队front和rear指针均指向p结点,否则将p插入到单链表的末尾,并让rear指针指向它。
本算法的时间复杂度为O(1)
出队列
bool deQueue(LinkQuNode *&q,ElemType &e)
{
DataNode *t;
if (q->rear==NULL) //队列为空
return false;
t=q->front; //t指向第一个数据结点
if (q->front==q->rear) //队列中只有一个结点时
q->front=q->rear=NULL;
else //队列中有多个结点时
q->front=q->front->next;
e=t->data;
free(t);
return true;
}
先判断队列是否为空,如果为空则返回false,否则将首结点的值赋给e,并将其删除,如果队列中只有一个元素,则需将链队的front和rear均置为NULL,表示链队为空,最后返回true。
本算法的时间复杂度为O(1)
三、完整代码
顺序队
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct
{
ElemType data[MaxSize];
int front,rear; //队头和队尾指针
} SqQueue;
void InitQueue(SqQueue *&q)
{ q=(SqQueue *)malloc (sizeof(SqQueue));
q->front=q->rear=-1;
}
void DestroyQueue(SqQueue *&q) //销毁队列
{
free(q);
}
bool QueueEmpty(SqQueue *q) //判断队列是否为空
{
return(q->front==q->rear);
}
bool enQueue(SqQueue *&q,ElemType e) //进队
{ if (q->rear==MaxSize-1) //队满上溢出
return false; //返回假
q->rear++; //队尾增1
q->data[q->rear]=e; //rear位置插入元素e
return true; //返回真
}
bool deQueue(SqQueue *&q,ElemType &e) //出队
{ if (q->front==q->rear) //队空下溢出
return false;
q->front++;
e=q->data[q->front];
return true;
}
int main()
{
SqQueue *q; //创建队列q
ElemType e;
InitQueue(q); //初始化队
enQueue(q,'a');
enQueue(q,'b');
enQueue(q,'c'); //依次进队a,b,c
deQueue(q,e);
printf("%c\n",e); //出队元素a
deQueue(q,e);
printf("%c\n",e); //出队元素b
deQueue(q,e);
printf("%c\n",e); //出队元素c
DestroyQueue(q); //销毁队
return 0;
}
链队文章来源:https://www.toymoban.com/news/detail-739967.html
#include <stdio.h>
#include <malloc.h>
typedef char ElemType;
typedef struct DataNode
{
ElemType data;
struct DataNode *next;
} DataNode; //链队数据结点类型
typedef struct
{
DataNode *front;
DataNode *rear;
} LinkQuNode; //链队类型
void InitQueue(LinkQuNode *&q)
{
q=(LinkQuNode *)malloc(sizeof(LinkQuNode));
q->front=q->rear=NULL;
}
void DestroyQueue(LinkQuNode *&q)
{
DataNode *p=q->front,*r;//p指向队头数据结点
if (p!=NULL) //释放数据结点占用空间
{ r=p->next;
while (r!=NULL)
{ free(p);
p=r;r=p->next;
}
}
free(p);
free(q); //释放链队结点占用空间
}
bool QueueEmpty(LinkQuNode *q)
{
return(q->rear==NULL);
}
void enQueue(LinkQuNode *&q,ElemType e)
{ DataNode *p;
p=(DataNode *)malloc(sizeof(DataNode));
p->data=e;
p->next=NULL;
if (q->rear==NULL) //若链队为空,则新结点是队首结点又是队尾结点
q->front=q->rear=p;
else
{ q->rear->next=p; //将p结点链到队尾,并将rear指向它
q->rear=p;
}
}
bool deQueue(LinkQuNode *&q,ElemType &e)
{ DataNode *t;
if (q->rear==NULL) //队列为空
return false;
t=q->front; //t指向第一个数据结点
if (q->front==q->rear) //队列中只有一个结点时
q->front=q->rear=NULL;
else //队列中有多个结点时
q->front=q->front->next;
e=t->data;
free(t);
return true;
}
int main()
{
LinkQuNode *q; //创建队列q
ElemType e;
InitQueue(q); //初始化队
enQueue(q,'a');
enQueue(q,'b');
enQueue(q,'c'); //依次进队a,b,c
deQueue(q,e);
printf("%c\n",e); //出队元素a
deQueue(q,e);
printf("%c\n",e); //出队元素b
deQueue(q,e);
printf("%c\n",e); //出队元素c
DestroyQueue(q); //销毁队
return 0;
}
参考资料:
李春葆《数据结构教程》(第五版)文章来源地址https://www.toymoban.com/news/detail-739967.html
到了这里,关于数据结构之队列(顺序队和链队)(C语言附完整代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!