1. 程式人生 > 實用技巧 >資料結構與演算法——佇列(順序儲存)

資料結構與演算法——佇列(順序儲存)

佇列 (Queue)概念

它是一種運算受限的線性表,先進先出(FIFO First In First Out),它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作。

採用陣列來儲存佇列的元素,設立一個隊首指標 front ,一個隊尾指標 rear,分別指向隊首和隊尾元素。則 rear-front 即為儲存的元素個數!

1 #define MaxSize 5                //佇列的最大容量 
2 typedef int DataType;            //佇列中元素型別
3 
4 typedef struct Queue
5 {
6     DataType queue[MaxSize];
7 int front; //隊頭指標 8 int rear; //隊尾指標 9 }SeqQueue;

佇列的初始化

1 //佇列初始化,將佇列初始化為空佇列
2 void InitQueue(SeqQueue* SQ)
3 {
4     if (!SQ) return;
5     SQ->front = SQ->rear = NULL; //把對頭和隊尾指標同時置0
6 }

佇列為空

1 //判斷佇列為空
2 int IsEmpty(SeqQueue* SQ)
3 {
4     if (!SQ) return
0; 5 if (SQ->front == SQ->rear) 6 { 7 return 1; 8 } return 0; 9 }

佇列為滿

1 //判斷佇列是否為滿
2 int IsFull(SeqQueue *SQ)
3 { if(!SQ) return 0;
4 if (SQ->rear == MaxSize)
5 { return 1;
6 } return 0;
7 }

入隊

將新元素插入 rear 所指的位置,然後 rear 加 1。

 1 //入隊,將元素data插入到佇列SQ中
 2 int EnterQueue(SeqQueue* SQ, DataType data)
3 { 4 if (!SQ) return 0; 5 if (IsFull(SQ)) 6 { 7 cout << "無法插入元素 " << data << ", 佇列已滿!" << endl; return 0; 8 } 9 SQ->queue[SQ->rear] = data;   //在隊尾插入元素data 10 SQ->rear++; //隊尾指標後移一位 11 12 return 1; 13 }

列印佇列中的元素

1 void PrintQueue(SeqQueue* SQ)
2 {
3     if (!SQ) return;
4     int i = SQ->front; while (i < SQ->rear)
5     {
6         cout << setw(4) << SQ->queue[i]; i++;
7     }
8     cout << endl;
9 }

出隊方式一

刪除 front 所指的元素, 後面所有元素前移 1 並返回被刪除元素

 1 int DeleteQueue(SeqQueue * SQ, DataType * data) 
 2 {
 3     if (!SQ || IsEmpty(SQ)) 
 4     {
 5         cout << "佇列為空!" << endl;
 6         return 0;
 7     } if (!data) return 0;
 8     *data = SQ->queue[SQ->front];
 9     for (int i = SQ->front + 1; i < SQ->rear; i++) 
10     {
11         //移動後面的元素 
12         SQ->queue[i-1]=SQ->queue[i];
13     }
14     SQ->rear--;                    //隊尾指標前移一位 
15     return 1;
16 }

出隊方式二

刪除 front 所指的元素,然後加 1 並返回被刪元素。

 1 int DeleteQueue2(SeqQueue * SQ, DataType * data)
 2 {
 3     if (!SQ || IsEmpty(SQ))
 4     {
 5         cout << "佇列為空!" << endl;
 6         return 0;
 7     }
 8     if (SQ->front >= MaxSize) {
 9         cout << "佇列已到盡頭!" << endl;
10         return 0;
11     }
12     *data = SQ->queue[SQ->front];    //出隊元素值 
13     SQ->front = (SQ->front)+1;      //隊首指標後移一位 
14     return 1;
15 }

取隊首元素

返回 front 指向的元素值

1 int GetHead(SeqQueue* SQ, DataType* data)
2 {
3     if (!SQ || IsEmpty(SQ))
4     {
5         cout << "佇列為空!" << endl;
6     }
7     return *data = SQ->queue[SQ->front];
8 }

清空佇列

1 void ClearQueue(SeqQueue* SQ)
2 {
3     if (!SQ) return;
4     SQ->front = SQ->rear = 0;
5 }

獲取佇列中元素的個數

1 int getLength(SeqQueue* SQ) 
2 {
3     if (!SQ) return 0;
4     return SQ->rear - SQ->front;
5 }

完整程式碼實現

  1 #include <stdio.h>
  2 #include <assert.h>
  3 #include <Windows.h>
  4 #include <iostream> 
  5 #include <iomanip> 
  6 
  7 using namespace std;
  8 
  9 #define MaxSize 5            //佇列的最大容量 
 10 typedef int DataType;        //佇列中元素型別
 11 
 12 typedef struct Queue
 13 {
 14     DataType queue[MaxSize];
 15     int front;                //隊頭指標 
 16     int rear;                //隊尾指標
 17 }SeqQueue;
 18 
 19 
 20 //佇列初始化,將佇列初始化為空佇列
 21 void InitQueue(SeqQueue* SQ)
 22 {
 23     if (!SQ) return;
 24     SQ->front = SQ->rear = 0; //把對頭和隊尾指標同時置0
 25 }
 26 
 27 //判斷佇列為空
 28 int IsEmpty(SeqQueue* SQ)
 29 {
 30     if (!SQ) return 0;
 31     if (SQ->front == SQ->rear)
 32     {
 33         return 1;
 34     } return 0;
 35 }
 36 
 37 //判斷佇列是否為滿
 38 int IsFull(SeqQueue* SQ)
 39 {
 40     if (!SQ) return 0;
 41     if (SQ->rear == MaxSize)
 42     {
 43         return 1;
 44     } return 0;
 45 }
 46 
 47 //入隊,將元素data插入到佇列SQ中
 48 int EnterQueue(SeqQueue* SQ, DataType data)
 49 {
 50     if (!SQ) return 0;
 51     if (IsFull(SQ))
 52     {
 53         cout << "無法插入元素 " << data << ", 佇列已滿!" << endl; return 0;
 54     }
 55     SQ->queue[SQ->rear] = data; //在隊尾插入元素data 
 56     SQ->rear++;                    //隊尾指標後移一位
 57 
 58     return 1;
 59 }
 60 
 61 //列印佇列中的各元素
 62 void PrintQueue(SeqQueue* SQ)
 63 {
 64     if (!SQ) return;
 65     int i = SQ->front; while (i < SQ->rear)
 66     {
 67         cout << setw(4) << SQ->queue[i]; i++;
 68     }
 69     cout << endl;
 70 }
 71 
 72 //出隊,將佇列中隊頭的元素data出隊,後面的元素向前移動
 73 int DeleteQueue(SeqQueue * SQ, DataType * data) 
 74 {
 75     if (!SQ || IsEmpty(SQ)) 
 76     {
 77         cout << "佇列為空!" << endl;
 78         return 0;
 79     } if (!data) return 0;
 80     *data = SQ->queue[SQ->front];
 81     for (int i = SQ->front + 1; i < SQ->rear; i++) 
 82     {
 83         //移動後面的元素 
 84         SQ->queue[i-1]=SQ->queue[i];
 85     }
 86     SQ->rear--;                    //隊尾指標前移一位 
 87     return 1;
 88 }
 89 
 90 //出隊2,將佇列中隊頭的元素data出隊,出隊後隊頭指標front後移一位
 91 int DeleteQueue2(SeqQueue * SQ, DataType * data)
 92 {
 93     if (!SQ || IsEmpty(SQ))
 94     {
 95         cout << "佇列為空!" << endl;
 96         return 0;
 97     }
 98     if (SQ->front >= MaxSize) {
 99         cout << "佇列已到盡頭!" << endl;
100         return 0;
101     }
102     *data = SQ->queue[SQ->front];    //出隊元素值 
103     SQ->front = (SQ->front)+1;    //隊首指標後移一位 
104     return 1;
105 }
106 
107 //獲取隊首元素,返回 front 指向的元素值
108 int GetHead(SeqQueue* SQ, DataType* data)
109 {
110     if (!SQ || IsEmpty(SQ))
111     {
112         cout << "佇列為空!" << endl;
113     }
114     return *data = SQ->queue[SQ->front];
115 }
116 
117 //清空佇列
118 void ClearQueue(SeqQueue* SQ)
119 {
120     if (!SQ) return;
121     SQ->front = SQ->rear = 0;
122 }
123 
124 //獲取佇列中元素的個數
125 int getLength(SeqQueue* SQ) {
126     if (!SQ) return 0;
127     return SQ->rear - SQ->front;
128 }
129 
130 int main()
131 {
132     SeqQueue* SQ = new SeqQueue;
133     DataType data = -1;
134 
135     //初始化佇列
136     InitQueue(SQ);
137 
138     //入隊
139     for (int i = 0; i < 7; i++) 
140     {
141         EnterQueue(SQ, i);
142     }
143 
144     //列印佇列中的元素    11
145     printf("佇列中的元素(總共%d 個):", getLength(SQ));
146 
147     PrintQueue(SQ); 
148     cout << endl;
149 
150     ////出隊
151     //for(int i=0; i<10; i++)
152     //{ 
153     //    if(DeleteQueue2(SQ, &data))
154     //    { 
155     //        cout<<"出隊的元素是:"<<data<<endl;    
156     //    }
157     //    else 
158     //    {
159     //        cout << "出隊失敗!" << endl;
160     //    }
161     //}
162 
163     //列印佇列中的元素 
164     printf("出隊一個元素後,佇列中剩下的元素:");
165     PrintQueue(SQ); 
166     cout << endl;
167     system("pause"); 
168     return 0;
169 }

===================================================================================================================