队列概念:
队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为“队尾”,允许进行删除操作的一端称为“队头”。当线性表中没有元素时,称为“空队”。特点 :先进先出(FIFO)。
队列的特征:
特殊的线性表,先进先出(FIFO)。
1)数据:
对于非空的队列,表头没有直接前驱,表尾没有直接后继,其它有且仅有一个直接前驱和一个直接后继。
2)操作:
只允许在表尾插入数据,在表头删除数据
顺序队列
typedef int datatype ; /*定义队列中数据元素的数据类型*/
#define MAXSIZE 64 /*定义队列的容量*/
typedef struct
{
datatype data[MAXSIZE] ; /*用数组作为队列的储存空间*/
int front,rear ; /*指示队头位置和队尾位置的指针*/
} sequeue ; /*顺序队列类型定义*/
sequeue *sq ; /*定义指向顺序队列的指针*/
初始化
算法思路:
首先使用malloc()函数申请内存,申请成功后,设置队头和队尾。
void init_seqqueue(seq_pqueue *Q)
{
*Q=(seq_pqueue)malloc(sizeof(seq_queue));
if((*Q)==NULL)
{
perror("malloc");
exit(-1);
}
(*Q)->front=(*Q)->rear=MAXSIZE-1;
return;
}
判断是否为空
算法思路:当队头和队尾指针在同一位置时,队空。q->rear == q->front)
bool is_empty_seqqueue(seq_pqueue q)
{
if(q->rear == q->front)
return true;
else
return false;
}
判断是否为满
算法思路:队头指针在队尾指针的下一位置时,队满 因为队头指针可能又重新从0位置开始,而此时队尾指针是MAXSIZE - 1,所以需要求余;少用一个存储空间,也就是数组的最后一个存数空间不用
bool is_full_seqqueue(seq_pqueue q)
{
if((q->rear+1)%MAXSIZE == q->front)
return true;
else
return false;
}
入队
算法思路:首先判断队列是否满,设置rear=rear+1(队列尾指针加1,指向入队列地址),将入队元素保存在rear指向的位置
bool in_seqqueue(datatype data,seq_pqueue q)
{
//判断队列是否满
if(is_full_seqqueue(q)){
printf("队列已满!\n");
return false;
}
//入对
q->rear=(q->rear+1)%MAXSIZE;
q->data[q->rear]=data;
return true;
}
出队
算法思路:
首先判断队列是否为空,从队列首部取出队头元素,修改队头front的序号,使其指向下一个。
bool out_seqqueue(seq_pqueue q,datatype *D)
{
//判断队列是否空
if(is_empty_seqqueue(q)){
printf("队列已空!\n");
return false;
}
//出队
q->front=(q->front+1)%MAXSIZE;
*D=q->data[q->front];
return true;
}
遍历队列
void show_seqqueue(seq_pqueue q)
{
int i;
if(is_empty_seqqueue(q))
return;
//非空时,从对头打印到队尾
for(i=(q->front+1)%MAXSIZE;i!=(q->rear+1)%MAXSIZE;i=(i+1)%MAXSIZE)
{
printf("%d\t",q->data[i]);
}
printf("\n");
}
test
/* 用循环队列实现如下功能:
* 用户从键盘输入整数,程序将其入对;
* 用户从键盘输入字母,程序将队头元素出队;
* 并在每一次出队和入队之后打印队列元素。
*/
int main(int argc, const char *argv[])
{
seq_pqueue q;
datatype data,t,ret;
init_seqqueue(&q);
while(1)
{
printf("请输入一个整数或字符:");
ret=scanf("%d",&data);
//输入整数时,入对
if(ret == 1)
{
if(in_seqqueue(data,q))
show_seqqueue(q);
}
else
{
//输入为字符时
if(out_seqqueue(q,&t))
{
printf("out:%d\n",t);
show_seqqueue(q);
}
//清空输入缓冲区
while(getchar()!='\n');
}
}
return 0;
}
链式队列
typedef int datatype ; /*定义链队列中数据元素的数据类型*/
typedef struct node
{
datatype data ; /*数据域*/
struct node *next ; /*链接指针域*/
} linklist ; /*链表元素类型定义*/
typedef struct
{
linklist *front , *rear ; /*链队列指针*/
} linqueue ; /*链队列类型定义*/
linkqueue *q ; /*定义指向链队列的指针*/
初始化
void init_linkqueue(link_pqueue *Q)
{
//申请front和rear的空间
*Q=(link_pqueue)malloc(sizeof(link_queue));
if((*Q)==NULL)
{
perror("malloc");
exit(-1);
}
//申请头结点空间
(*Q)->front=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
if((*Q)->front==NULL)
{
perror("malloc");
exit(-1) ;
}
(*Q)->front->next=NULL;
(*Q)->rear=(*Q)->front;
return;
}
判断空
bool is_empty_linkqueue(link_pqueue q)
{
if(q->rear == q->front)
return true;
else
return false;
}
入队
bool in_linkqueue(datatype data,link_pqueue q)
{
linkqueue_pnode new;
//申请数据结点空间
new=(linkqueue_pnode)malloc(sizeof(linkqueue_node));
if(new==NULL)
{
puts("入队失败!");
return false;
}
//将数据存储在申请的空间
new->data=data;
//将new指向的结点插入到链式队列中
new->next=q->rear->next;
q->rear->next=new;
//让rear指针指向新的队尾结点
q->rear=q->rear->next;
return true;
}
出队
bool out_linkqueue(link_pqueue q,datatype *D)
{
linkqueue_pnode t;
//判断队列是否空
if(is_empty_linkqueue(q)){
printf("队列已空!\n");
return false;
}
//出队
t=q->front;
q->front =q->front->next;
*D=q->front->data;
free(t);
return true;
}
遍历
void show_linkqueue(link_pqueue q)
{
linkqueue_pnode p;
if(is_empty_linkqueue(q))
return;
//非空时,从对头打印到队尾
for(p=q->front->next;p!=NULL;p=p->next)
{
printf("%d\t",p->data);
}
printf("\n");
}