队列简介
与栈结构相对的是队列结构,队列结构就像生活中的排队,其进出规则是”先进先出“。对于排队,想必大家都懂^_^
队列的数组实现:
先看一下结构定义:
typedef struct array2{
int data[SIZE];//数据域
int length;//数组长度
int head;//(head+1)记录队首下标
int end;//记录队尾下标
}array2;
队列的数组实现要使用模运算,其实现原理是通过对下标进行模运算使数组形成循环,头尾相接。这样就不用因为删除元素而移动数组了。数组的任意位置都可以是队列头和尾,关于模运算,请参见(…先挖个坑)。
这样当要求一个head+1后的位置的算法是:head = (head+1)模数组长度。要求一个下标 - n 后的位置的算法是:新下标 = 旧下标+(数组长度-n)模数组长度。
图示:
如图,当end = 5时,end+1 后的下标就是 end+1%length = 0,(5+1%6=0)。以此来实现循环。
队列的链表实现与 单链表 相似,在链尾添加元素,在链头取元素。这里不再重复。
具体实现代码如下:
#define SIZE 6
//定义结构
typedef struct array2{
int data[SIZE];
int length;
int head;
int end;
}array2;
//初始化
array2 *newArr2(){
array2 *arr = (array2 *)malloc(sizeof(array2));
//0下标空闲
arr->head = 0;
arr->end = 0;
arr->length = SIZE;
return arr;
}
//判空
int isEmpty2(array2 *arr){
return arr->head == arr->end;
}
//判满
int isFull(array2 *arr){
return (arr->end+1)%arr->length == arr->head;
}
//入队
void push2(array2 *arr ,int value){
int len;
if(isFull(arr)){
printf("the queue is full");
return;
}
//len = (arr->end++)%arr->length;//(arr->end++)即使在括号里面也是最后才加1
//printf("******************%d***%d\n",arr->end,len);
//arr->end--;
len = ++arr->end % arr->length;
arr->data[len] = value;
}
//出队
void pop2(array2 *arr){
if(isEmpty2(arr)){
printf("the queue is empty");
return;
}
arr->head = (arr->head + 1)%arr->length;
}
int *getHead(array2 *arr){
//因为要返回的数据是数值型,当没有此元素时(empty)要返回null,而c中的NULL是定义成0的,会和数字冲突,所以这里改成返回指针类型。
return isEmpty2(arr) ? NULL:&arr->data[arr->head+1];
}
void queueTest(){
array2 *arr = newArr2();
push2(arr,1);
push2(arr,2);
push2(arr,3);
while(!isEmpty2(arr)){
printf("get %d\n",*getHead(arr));
pop2(arr);
}
printf("-----------------------\n");
push2(arr,4);
push2(arr,5);
while(!isEmpty2(arr)){
printf("get %d\n",*getHead(arr));
pop2(arr);
}
}