循環列表
我們把隊列的這種頭尾相接的順序存儲結構稱爲循環隊列。
假溢出現象:
隊列滿的條件是 (rear+1) % QueueSlze==front。 (取模 “%” 的目的就是爲了整合rear與front大小爲一個問題)。
通用的計算隊列長度公式爲:(rear- front + QueueSize) %QueueSize。
代碼:
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存儲空間初始分配量 */
typedef int Status;
typedef int QElemType; /* QElemType 類型根據實際情況而定,這裏假設爲 int */
/*循環隊列的順序存儲結構*/
typedef struct
{
QElemType data[MAXSIZE];
int front;/*頭指針*/
int rear;/*尾指針,若隊列不空,指向隊列尾元素的下一個位置*/
}SqQueue;
/* 初始化一個空隊列Q*/
Status InitQueue(SqQueue *Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
/*將Q清爲空隊列*/
Status ClearQueue(SqQueue *Q)
{
Q->front = Q->rear = 0;
return OK;
}
/*若隊列Q爲空隊列,則返回TRUE,否則返回FASLE*/
Status QueueEmpty(SqQueue Q)
{
if (Q.front == Q.rear)/*隊列空的標誌*/
return TRUE;
else
return FALSE;
}
/*返回Q的元素個數,也就是隊列的當前長度*/
int QueueLength(SqQueue Q)
{
return (Q.rear - Q.front + MAXSIZE) % MAXSIZE;
}
/* 若隊列不空,則用e返回Q的隊頭元素,並返回OK,否則返 ERROR */
Status GetHead(SqQueue Q, QElemType *e)
{
if (Q.front == Q.rear) /*隊列空*/
return ERROR;
*e = Q.data[Q.front];
return OK;
}
/*若隊列未滿,則插入元素e爲Q新的隊尾元素*/
Status EnQueue(SqQueue *Q, QElemType e)
{
if ((Q->rear + 1) % MAXSIZE == Q->front)/*隊列滿的判斷*/
return ERROR;
Q->data[Q->rear] = e; /*將元素e賦值給隊尾*/
Q->rear = (Q->rear + 1) % MAXSIZE; /*rear指針向後移一位置,
若到最後則轉到數組頭部*/
return OK;
}
/*若隊列不空,則刪除Q中隊頭元素,用e返回其值*/
Status DeQueue(SqQueue *Q, QElemType *e)
{
if (Q->front == Q->rear)/*隊列空的判斷*/
return ERROR;
*e = Q->data[Q->front]; /*將隊頭元素賦值給e*/
Q->front = (Q->front + 1) % MAXSIZE; /*front指針向後移一位置
若到最後則轉到數組頭部*/
return OK;
}
Status visit(QElemType c)
{
printf("%d ", c);
return OK;
}
/*從隊頭到隊尾依次對隊列Q中每個元素輸出*/
Status QueueTraverse(SqQueue Q)
{
int i = Q.front;
while ((i + Q.front) != Q.rear)
{
visit(Q.data[i]);
i = (i + 1) % MAXSIZE;
}
printf("\n");
return OK;
}
總結
要理解循環隊列中循環的意思!