队列
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。
队列:先进先出
队列的抽象数据类型
InitQueue(*Q): 初始化操作,建立一个空队列Q。
DestroyQueue(*Q): 若队列Q存在,则销毁它。
ClearQueue(*Q): 将队列Q清空。
QueueEmpty(Q): 若队列Q为空,返回true,否则返回false。
GetHead(Q, *e): 若队列Q存在且非空,用e返回队列Q的队头元素。
EnQueue(*Q, e): 若队列Q存在,插⼊新元素e到队列Q中并成为队尾元素。
DeQueue(*Q, *e): 删除队列Q中队头元素,并用e返回其值。
QueueLength(Q): 返回队列Q的元素个数
顺序存储
改进:
为了解决假溢出,就出现了循环队列
循环队列
也就是让front或rear指针不断加1,即时超出了地址范围,也会自动从头开始。我们可以采取取模运算处理:
(rear+1) % QueueSize
(front+1) % QueueSize
/***************************************
* 数据结构和算法--小甲鱼
* 队列循环队列
****************************************/
#include <stdio.h>
#include <stdlib.h>
typedef int ElemType;
#define MAXSIZE 100
//定义一个循环队列
typedef struct
{
ElemType *base; //用于存放内存分配的基地址
//也可以用数组来存放
int front;
int rear;
} cycleQueue;
//初始化一个循环队列
int initQueue( cycleQueue *q)
{
q->base = (ElemType *) malloc (MAXSIZE * sizeof(ElemType));
if(!q->base)
return 0;
q->front = q->rear = 0;
return 1;
}
//入循环队列
int InsertQueue(cycleQueue *q, ElemType e)
{
if((q->rear + 1) % MAXSIZE == q->front)
return 0; //说明队列已经满了
q->base[q->rear] = e;
q->rear = (q->rear + 1) %MAXSIZE ;
return 1;
}
//出队列的操作
int DeleteQueue (cycleQueue *q , ElemType *e)
{
if(q->front == q->rear)
return 0; //说明队列为空,没有可以移出的东西
*e = q->base[q->front]; //元素出队列
q->front = (q->front + 1) % MAXSIZE;
return 1;
}
int main()
{
return 0;
}
链式存储
/***************************************
* 数据结构和算法--小甲鱼
* 队列的链式存储
****************************************/
#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct QNode
{
ElemType data;
struct QNode *next;
} QNode ,*QueuePtr; //定义队列的结点
typedef struct
{
QueuePtr front,rear;//指向队列的队尾 和 队头
}LinkQueue; //定义队列的指针
//初始化一个队列
int initQueue (LinkQueue *q)
{
q->front = q->rear = (QueuePtr) malloc (sizeof(QNode));
if(!q->front)
return -1; //表示出错了
q->front->next = NULL; //头节点为空
}
//队尾入元素
InsertQueue(LinkQueue *p , ElemType *e)
{
//首先是创建一个结点
QueuePtr newP= (QueuePtr) malloc (sizeof(QNode));
if(!newP)
return -1; //创建失败了
//承接元素
newP ->data = e;
newP ->next = NULL;
//开始链接
p->rear->next = newP; //连接完毕
p->rear = newP; //开始移动指针
}
//队头出元素
int DeleteQueue( LinkQueue *p , ElemType *e)
{
QueuePtr newP;
//首先是判断是否为空
if(p->front == p->rear)
return -1; //为空没有元素
newP = p->front->next;
*e = newP->data;
p->front->next = newP->next;
if( p->rear == newP)
{
p->rear = p->front;
}
free(newP); // 释放结点
return 1; //结束
}
int DestroyQueue(LinkQueue *q)
{
while( q->front ) {
q->rear = q->front->next;
free( q->front );
q->front = q->rear;
}
}
int main()
{
ElemType e;
LinkQueue q;
initQueue(&q);
printf("请输入一个字符串,以井号键结束输入:");
scanf("%c", &e);
while( e != '#' )
{
InsertQueue( &q, e );
scanf("%c", &e);
}
printf("打印队列中的元素:");
while( q.front != q.rear )
{
DeleteQueue( &q, &e );
printf("%c", e);
}
return 0;
}