队列的顺序存储结构,因为普通顺序结构因为出队列会浪费内存空间,所以应使用循环队列。
循环队列里应该注意区分队列满、队列空的情况,我的代码里采用了少用一个元素空间的方式(front指向的为空)。
/*
*循环队列
*为了区分 front == rare到底是队列满还是队列空,不在front指向内存中存放元素
*/
# include <stdio.h>
# include <malloc.h>
# define MAXSIZE 20
typedef struct QNode{
int front,rear; //头尾指针
int * data;
}QNode;
typedef QNode * PQNode;
//初始化一个空循环队列
PQNode init(){
PQNode p = (PQNode)malloc(sizeof(QNode));
p->data = (int *)malloc(sizeof(int) * MAXSIZE);
p->front = p->rear = 0; //为空时,front rear 都指向0
return p;
}
//获取队列中元素个数
int getLength(PQNode p){
if(p->rear == p->front)
return 0;
return (p->rear - p->front + MAXSIZE) % MAXSIZE;
}
//插入队列
PQNode add(PQNode l, int data){
if(l->rear + 1 == l->front){ //判断队列是否满
printf("队列满!");
return l;
}else{
l->rear = (l->rear + 1) % MAXSIZE;
l->data[l->rear] = data;
return l;
}
}
//出队列
int remove(PQNode p){
if(getLength(p) == 0){ //判断队列是否为空
printf("队列为空,出队失败!");
return NULL;
}else{
p->front = (p->front + 1) % MAXSIZE;
int val = p->data[p->front];
p->data[p->front] = NULL;
return val;
}
}
//test
int main (void){
PQNode p = init();
int length = getLength(p);
printf("初始化的一个循环队列元素数位:%d\n", length);
add(p,1);
add(p,2);
add(p,3);
length = getLength(p);
printf("插入三个元素后元素数位:%d\n", length);
int val = remove(p);
length = getLength(p);
printf("出队列元素为:%d, 出队列后长度为:%d:\n", val, length);
return 0;
}
队列的链式存储结构
/*
*链队列
*/
# include <stdio.h>
# include <malloc.h>
typedef struct Node{
int data;
struct Node * next;
}QNode, *PQNode;
typedef struct {
PQNode rear;
PQNode front;
}LinkQueue;
//初始化一个队列
LinkQueue init(){
LinkQueue l;
l.front = l.rear = (PQNode)malloc(sizeof(QNode));
l.front->next = NULL; //初始化一个头结点
return l;
}
//入队
LinkQueue add(LinkQueue &l, int data){
PQNode p = (PQNode)malloc(sizeof(QNode)); //创建一个新结点
p->data = data;
p->next = NULL;
l.rear->next = p;
l.rear = p;
return l;
}
//获取队列的长度
int getLength(LinkQueue l){
int length = 0;
PQNode p = l.front;
while(p->next){
length++;
p = p->next;
}
return length;
}
//出队
LinkQueue del(LinkQueue &l){
if(getLength(l) == 0){
printf("队列空,无法出队!\n");
return l;
}
PQNode target = l.front->next;
l.front->next = target->next; //front指针后移动
free(target); //释放目标结点
return l;
}
//test
int main(void){
LinkQueue l = init();
add(l,1);
add(l,1);
add(l,1);
int length = getLength(l);
printf("入队三次后的长度:%d\n",length);
del(l);
length = getLength(l);
printf("出队一次后的长度:%d\n",length);
return 0;
}