順序佇列的基本演算法及迴圈佇列
阿新 • • 發佈:2019-01-30
佇列的順序儲存結構型別描述如下:
#define M 1000
QElemType queue[ M ];
int front, rear;
隊頭指標front指出實際隊頭元素所在位置的前一個位置,而隊尾指標rear指出實際隊尾元素所在的位置,初始時,佇列為空有front = rear = -1, 測試一個佇列是否為空的條件是front = rear.
順序佇列的基本演算法如下:
/* 順序佇列的基本演算法 */ #include<stdlib.h> #include<stdio.h> /* 佇列的順序儲存結構型別 */ #define M 1000 /* 初始化一個佇列 */ void initialQ( int *front, int *rear ){ *front = -1; *rear = -1; } /* 測試佇列是否為空 */ int isEmpty( int front, int rear ){ return front == rear; } /* 取當前隊頭元素 */ int getQ( int queue[ ], int front, int rear, int *item ){ if( isEmpty( front, rear ) ) /* 如佇列為空,操作失敗,返回0 */ return 0; else{ /* 取出對頭元素,操作成功,返回1 */ *item = queue[ front+1 ]; return 1; } } /* 佇列的插入,入隊 */ int addQ( int queue[ ], int *rear, int item ){ if( *rear == M-1 ) return 0; /* 佇列已滿,插入失敗,返回0 */ else{ queue[ ++( *rear ) ] = item; return 1; /* 佇列未滿,插入成功,返回1 */ } } /* 佇列的刪除,出隊 */ int deleteQ( int queue[ ], int *front, int rear, int *item ){ if( isEmpty( *front, rear ) ) /* 佇列為空,刪除失敗,返回0 */ return 0; else{ *item = queue[ ++( *front ) ]; /* 儲存隊頭元素,佇列頭指標後移1 */ return 1; } } void printQ( int queue[ ], int front, int rear ){ int p; printf( "the elem in queue is:" ); for( p = front + 1; p <= rear; p++ ){ printf( "%3d", queue[ p ] ); } } int main(){ int queue[ M ]; int front, rear; initialQ( &front, &rear ); printf( "the queue is empty %d\n", isEmpty( front, rear ) ); addQ( queue, &rear, 8 ); addQ( queue, &rear, 14 ); addQ( queue, &rear, 84 ); printQ( queue, front, rear ); int elem; deleteQ( queue, &front, rear, &elem ); printf( "the deleted elem is%d\n", elem ); getQ( queue, front, rear, &elem ); printf( "the front elem is %d\n", elem ); return 0; }
為了節省儲存空間,可使用迴圈佇列,初始化迴圈佇列時令front = rear = 0, 並且把佇列設想成頭尾相連的迴圈表,使得空間得以重複使用,在進行插入操作時,當佇列的第M個位置(陣列下標是M-1)被佔用後,只要佇列前面還有可用空間,新的元素加入佇列時就可以從第1個元素(陣列下標為0)開始,按照這種思路,插入演算法中修改隊尾指標的語句可以寫成:
if(rear == M-1)
rear = 0;
else
rear ++;
若修改後的隊尾指標滿足rear = front,那麼真的要產生溢位了,上述語句可用求模運算改寫成:
rear = (rear + 1) % M;
在刪除演算法中也可以有:
front = (front + 1) % M;
迴圈佇列的插入和刪除演算法如下:
/* 迴圈佇列的插入 */ int addCQ( int queue[ ], int front, int *rear, int item ){ if( (*rear + 1)%M == front ) /* 迴圈佇列已滿,插入失敗,返回0 */ return 0; else{ queue[ ++(*rear)%M ] = item; /* 迴圈佇列未滿,插入成功,返回1 */ return 1; } } /* 迴圈佇列的刪除 */ int deleteCQ( int queue[ ], int *front, int rear, int *item ){ if( *front == rear ) /* 迴圈佇列為空,刪除失敗,返回0 */ return 0; else{ *front = (*front + 1)%M; /* 刪除並儲存頭結點元素 */ *item = queue[ *front ]; return 1; } }
只有當rear 加1 以後從“後面”趕上來並等於front是才是迴圈佇列“滿”的情況,其餘情況下的front等於rear均表示迴圈佇列為空,應說明一點的是,此時迴圈佇列的“滿”,實際上還有一個空位置(僅一個), 用來區分“上溢” 和 “下溢”,頭指標所指位置為空位置,不存元素。