線性結構_循環隊列

線性結構的應用--隊列
定義:一種可以實現先進先出的存儲結構。
分類:鏈式隊列:用鏈表實現
靜態隊列:用數組實現(循環隊列)

循環隊列:
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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章