1. 程式人生 > >線性結構_迴圈佇列

線性結構_迴圈佇列

線性結構的應用--佇列 定義:一種可以實現先進先出的儲存結構。 分類:鏈式佇列:用連結串列實現 靜態佇列:用陣列實現(迴圈佇列) 迴圈佇列: 1、靜態佇列為什麼必須是迴圈佇列:佇列的結構是先進先出的,迴圈佇列可對記憶體重複使用,減少對記憶體的浪費。 2、迴圈佇列需要幾個引數來確定:2個引數:front和rear 3、迴圈佇列各個引數的含義 這兩個引數在不同場合有不同的含義: 1)、佇列的初始化:front和rear的值都是零 2)、佇列非空:front代表第一個元素,rear代表最後一個有效元素的下一個元素。 3)、佇列為空:front和rear相等但不一定為零。 4、迴圈佇列入隊的偽演算法:兩步完成 1)、將值存入r所代表的位置 2)、錯誤寫法:rear = rear + 1; 正確寫法:rear = (rear + 1)%陣列的長度 5、迴圈隊列出隊的偽演算法:front = (front + 1)%陣列長度 6、如何判斷迴圈佇列是否為空:如果rear和front相等,則佇列為空。 7、如何判斷迴圈佇列是否已滿:(當front==rear時,無法判斷佇列為空或滿) 1)只用n-1個元素,佇列滿時rear與front緊挨著(哪個在左邊的判斷) 2)使用一個變數標識引數,統計元素個數 迴圈佇列中,front與rear的大小關係沒有規律,初始化佇列時,front與rear的值都為零,但隨著佇列的不斷插入與刪除,front與rear的大小關係不確定。最初元素入隊階段,rear的值增加,rear的值比front大,但隨著佇列元素的處隊,以及新元素入隊進入迴圈佇列,會出現front的值比rear大的情況。 經常使用的是第一種方法,判斷結果如下:
if((rear + 1) % 陣列長度 == f){佇列已滿} else{佇列未滿} 佇列的具體運用:所有與時間有關的場合都有佇列的影子。
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>

typedef struct Queue {
	int *pBase;
	int front;
	int rear;
} QUEUE;
void init_Queue(QUEUE*);
bool en_Queue(QUEUE*, int);//入隊
bool out_Queue(QUEUE*, int*);//出隊
bool full_Queue(QUEUE*);//判斷佇列是否已滿
bool empty_Queue(QUEUE*);//判斷佇列是否為空
void traverse_Queue(QUEUE *);//遍歷佇列

int main() {
	QUEUE Q;
	int val;
	init_Queue(&Q);
	en_Queue(&Q, 1);
	en_Queue(&Q, 2);
	en_Queue(&Q, 3);
	en_Queue(&Q, 4);
	en_Queue(&Q, 5);
	en_Queue(&Q, 6);
	en_Queue(&Q, 7);
	en_Queue(&Q, 8);
	traverse_Queue(&Q);
	for (int i = 0; i < 8; i++) {
		if (out_Queue(&Q, &val)) {
			printf("出隊成功,出隊的元素是:%d\n", val);
		}
		else {
			printf("出隊失敗。\n");
		}
		traverse_Queue(&Q);
	}
	return 0;
}

void init_Queue(QUEUE *pQ) {
	pQ->pBase = (int*)malloc(sizeof(int) * 6);		//建立一個pBase陣列,有6個元素,但只存放5個元素,pBase指向陣列的第一個元素
	pQ->front = 0;
	pQ->rear = 0;
}

/*迴圈佇列入隊的偽演算法:兩步完成
1)、將值存入r所代表的位置
2)、錯誤寫法:rear = rear + 1; 正確寫法:rear = (rear + 1) % 陣列的長度*/

bool en_Queue(QUEUE *pQ, int val) {
	if (full_Queue(pQ)) {
		return false;
	}
	else {
		pQ->pBase[pQ->rear] = val;
		pQ->rear = (pQ->rear + 1) % 6;
		return true;
	}
}

/*如何判斷迴圈佇列是否已滿:(當front == rear時,無法判斷佇列為空或滿)
1)只用n - 1個元素,佇列滿時rear與front緊挨著(哪個在左邊的判斷)
2)使用一個變數標識引數,統計元素個數
經常使用的是第一種方法,判斷結果如下:
if ((rear + 1) % 陣列長度 == f) { 佇列已滿 }
else { 佇列未滿 }*/
bool full_Queue(QUEUE *pQ) {
	if ((pQ->rear + 1) % 6 == pQ->front) {
		return true;
	}
	else return false;
}
/*迴圈隊列出隊的偽演算法:front = (front + 1)%陣列長度*/
bool out_Queue(QUEUE* pQ, int* pVal) {
	if (empty_Queue(pQ)) {
		return false;
	}
	else {
		*pVal = pQ->pBase[pQ->front];
		pQ->front = (pQ->front + 1) % 6;
		return true;
	}
}

/*佇列為空:front和rear相等但不一定為零。*/
bool empty_Queue(QUEUE* pQ) {
	if (pQ->front == pQ->rear) {
		return true;
	}
	else return false;
}

/*遍歷佇列
從佇列的front處開始遍歷
建立一個統計變數cnt,當cnt等於rear時,遍歷輸出終止
因為rear指向的時最後一個元素的下一個位置,不存在資料
*/

void traverse_Queue(QUEUE *pQ) {
	int cnt = pQ->front;
	while (cnt != pQ->rear) {
		printf("%d ", pQ->pBase[cnt]);
		cnt = (cnt + 1) % 6;
	}
	printf("\n");
	return;
}