老师为了统一函数的形参都用的二级指针,但其实有的一级指针就可以了
重点是判断队是空(is_empty)是满(is_full)的函数,还有写入数(push_qeuce)的函数,写入数的函数要判断当队不满但是已达到数组上限是要整个前移。
其中buttom所代表的下标+1开始到top所代表的下标结束有数字存放(或者说这些数字是有效的),当数字出队时,buttom先后移再输出指向的数字,但这个数字之后不会被清空,用buttom表示就可以。
当最后一个数字到达上限时,也可以不前移,而是将数组当做一个循环,再在开头开始写入数字。(下面的这个带啊用的是前移不是循环)
具体:
-
队列存放数组被当作首尾相接的表处理。
-
队头、队尾指针加1时从QueueSize -1直接进到0,可用语言的取模(余数)运算实现。
-
队头指针进1: front = (front+1) % QueueSize;
-
队尾指针进1: rear = (rear+1) % QueueSize;
-
队列初始化:front = rear = 0;
-
队空条件:front == rear;
-
队满条件:(rear+1) % QueueSize == front
所以综上再结合图,一个QueueSize大小的的队只能放QueueSize-1个数字
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
enum return_result{FULL_OK,FULL_NO,EMPTY_OK,EMPTY_NO,PUSH_OK};
struct quece_data
{
int quece[MAX_SIZE];
int top;
int buttom;
};
typedef struct quece_data Quece;
void create_quece(Quece **quece)
{
*quece = (Quece *)malloc(sizeof(struct quece_data));
//应该还要加上判断是否申请成功?
//if(*quece == NULL)
//{
// printf("创建失败!\n");
// exit(-1);
//}
}
void init_quece(Quece **quece)
{
(*quece)->top = -1;
(*quece)->buttom = -1;
}
int is_full(Quece ** quece)
{
if((*quece)->buttom == -1)
{
if((*quece)->top == MAX_SIZE - 1)
return FULL_OK;
}
return FULL_NO;
}
int is_empty(Quece **quece)
{
if((*quece)->top <= (*quece)->buttom)
{
return EMPTY_OK;
}
return EMPTY_NO;
}
int push_quece(Quece **quece, int num)
{
int i ;
if(is_full(quece) == FULL_OK)
{
printf("the quece is full!\n");
exit(FULL_OK);
}
if((*quece)->top < MAX_SIZE - 1)
{
((*quece)->top)++;
((*quece)->quece[(*quece)->top]) = num;
}
else
{
for( i = (*quece)->buttom + 1;i <= (*quece)->top; i++)
{
(*quece)->quece[i - (*quece)->buttom - 1] = (*quece)->quece[i];
}
(*quece)->top = (*quece)->top - (*quece)->buttom - 1;
(*quece)->buttom = -1;
((*quece)->top)++;
((*quece)->quece[(*quece)->top]) = num;
}
return PUSH_OK;
}
int pop_quece(Quece **quece)
{
if(is_empty(quece) == EMPTY_OK)
{
printf("the quece is empty!\n");
exit(EMPTY_OK);
}
return ((*quece)->quece[++((*quece)->buttom)]);
}
int main()
{
Quece *quece;
create_quece(&quece);
init_quece(&quece);
int i;
for(i = 0; i < 10; i++)
{
if(push_quece(&quece,i+1) == PUSH_OK)
{
printf("push num:\t %d\n",i+1);
}
}
for(i = 0; i < 1; i++)
{
printf("pop num:\t %d\n",pop_quece(&quece));
}
for(i = 0; i < 8; i++)
{
if(push_quece(&quece,i+1) == PUSH_OK)
{
printf("push num:\t %d\n",i+1);
}
}
return 0;
}
以下用的是循环的方法,就像一开始解释的一样
只能放SIZE-1个数据,还有一个空间必须空着
小bug:PopQueue不成功的返回值是0,如果输入数据也有0.。。。就不太好了
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
struct queue_struct
{
int data[SIZE];
int top;
int buttom;
};
typedef struct queue_struct Queue;
void CreateQueue(Queue **q)
{
*q = (Queue *)malloc(sizeof(Queue));
if(*q == NULL)
{
exit(-1);
}
}
void InitQueue(Queue *q)
{
q->top = 0;
q->buttom = 0;
}
int IsEmpty(Queue *q) //空就返回1,非空就返回0
{
if(q->top == q->buttom)
{
return 1;
}
return 0;
}
int IsFull(Queue *q) //满就返回1,非满就返回0
{
if((q->top + 1) % SIZE == q->buttom)
{
return 1;
}
return 0;
}
int PushQueue(Queue *q, int num)
{
if(IsFull(q))
{
printf("FULL!!!\n");
return 0;
}
q->top = (q->top + 1) % SIZE;
q->data[q->top] = num;
return 1;
}
int PopQueue(Queue *q)
{
int temp;
if(IsEmpty(q))
{
printf("Empty!!!\n");
return 0;
}
temp = q->buttom;
q->buttom = (q->buttom + 1) % SIZE;
return q->data[temp];
}
int main()
{
Queue *q;
CreateQueue(&q);
InitQueue(q);
PopQueue(q);
PushQueue(q,1);
PushQueue(q,2);
PushQueue(q,3);
PushQueue(q,4);
PushQueue(q,5);
PushQueue(q,6);
PushQueue(q,7);
PushQueue(q,8);
PushQueue(q,9);
PushQueue(q,10);
PopQueue(q);
PopQueue(q);
PopQueue(q);
PushQueue(q,1);
PushQueue(q,2);
PushQueue(q,3);
PushQueue(q,4);
return 0;
}
运行结果:也表明里面只能放9个数字,不能放10个