1. 程式人生 > >佇列的兩種儲存方式的介紹與實現

佇列的兩種儲存方式的介紹與實現

簡介

佇列是一種特殊的線性表,它的特殊之處在於它必須在佇列的頭部進行刪除元素,在佇列尾部插入元素。我們把佇列的頭部稱為對頭(front),佇列尾部叫做隊尾(rear)。進行刪除元素位置叫隊頭(front),進行插入元素的位置叫在隊尾(rear)。
佇列的儲存的資料稱為佇列元素,因為只能在對頭進行刪除的操作,隊尾進行插入,先插入的先出隊,所以我們可以稱佇列為一種先進先出(FIFO:first in first out )的資料結構。

順序佇列

建立順序儲存結構,我們必須動態申請或靜態地分配一塊儲存位置,設定兩個指標來進行管理,分別稱為對頭head、隊尾tail,當隊頭與隊尾相等時
(head==tail)我們稱為隊空。隊頭指標指向佇列第一個插入的元素,tail指標指向佇列最後一個插入元素的下一個位置,當佇列中插入一個元素時,tail+1;刪除
一個元素時,head+1。
我們來看一個圖:

在圖中我們可以到,圖1.3,當隊頭元素被刪除後,會留下一塊儲存區域,它並不會再次被使用,所以會造成記憶體的浪費。圖1.4中反應了這樣一個現象,當佇列所
申請的記憶體最後一塊儲存空間被佔有時,當想要再插入一個新的元素時,就會產生問題,這種現象稱為“假溢位”。
為了避免上述的問題,因此出現了一個新的概念:迴圈佇列。

迴圈佇列

迴圈佇列,我們假想成一個迴圈模型,如下圖所示:

當front==rear時表示隊空;當迴圈出佇列、入佇列的過程中會發生一種情況,隊尾在元素一的位置,隊頭在元素二的位置,那麼頭尾指標也恰好指向同一個位置,這時我們稱為隊滿,是不是也是front==rear?

這裡我用陣列方式來實現迴圈佇列:

typedef int QueType;
typedef int Status;
#define capacity 4
*採用資料儲存元素,陣列型別為:int
*實現佇列初始化、出佇列、入佇列、統計佇列總數、迴圈遍歷佇列元素等功能。
*/
typedef struct{

	int head;//頭
	int tail;//尾
    
	QueType queArr[capacity];//佇列陣列
	
}myQueue; 

//佇列初始化
int InitQueue(myQueue *q){
	//q = (myQueue *)malloc(sizeof(myQueue));
	q->head = q->tail = 0 ;//頭和尾相等,此時為空    
	return 0;
}

//判斷佇列是否為空
//為空返回0,否則為-1
int QueueEmpity(myQueue *q){
	if(q->head == q->tail){//首尾相等,佇列為空
		return 0;
	}
	return -1 ;
}

//判斷佇列是否已滿
//為空返回0,否則為-1
int QueueFull(myQueue *q){
    //避免和佇列為空時衝突。佇列中實際還差一個位置。
	if(q->head == (q->tail+1)%(capacity)){//為滿時,
		return 0;
	}
	return -1 ;
}

//入隊
Status EnQueueEle(myQueue *q , QueType ele){
    
	
	if(QueueFull(q) == -1){//不為滿
		
		q->queArr[q->head] = ele;
		
		//重置隊尾
		q->tail = (q->tail+1) % (capacity);
	}else{
		printf("佇列已滿\n");
		return -1;
	}
	
	return 0;
}

//出隊
int DeQueueEle( myQueue *q,QueType *ele){
	
	if(QueueEmpity(q) == -1){//不為空
		*ele = q->queArr[q->head];
		q->head ++;
        //重置隊首
		q->head = (q->head+1) % (capacity);
	}else{
		printf("佇列為空\n");
		return -1;
	}
	return 0;	
}

//獲取第一元素
int GetHead(myQueue *q ,QueType *ele){
	*ele = q->queArr[q->head];
	return 0;
}

//統計佇列元素個數
int getQueueSize(myQueue *q){
	
	return (capacity - q->head + q->tail)%(capacity) ;
}

//遍歷元素
void showQueueList(myQueue *q){
	
	int i,size ;
    size = getQueueSize(q);
	for(i = q->head ; i < size ;i++){
		printf("佇列中的元素:%d\n",q->queArr[i]);
		
	}

}
測試:
int main(void){
	
	int ret = 0;
	int size = 0;

    myQueue *que ;
	que = (myQueue *)malloc(sizeof(myQueue));
	//que->head = que->tail=0;
	InitQueue(que);
	

	EnQueueEle(que , 1);
	printf("增加一個元素\n");
    size = getQueueSize(que);
    printf("佇列元素個數為[%d]\n",size);
	showQueueList(que);
	free(que);
	return 0;
}

結果: