老師爲了統一函數的形參都用的二級指針,但其實有的一級指針就可以了
重點是判斷隊是空(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個