火車車廂重排——隊列實現


其實隊列和棧挺像的,所以也就沒有單獨寫一個實現隊列的筆記,可以參考一下棧的實現:https://www.cnblogs.com/2015-16/p/12957964.html    (同時這一篇也包含了隊列的一些基本使用)

隊列,簡稱隊,也是一種操作受限的線性表。把進行插入的一端稱做隊尾(rear),進行刪除的一端稱做隊頭(front);(先進先出表)

環形隊列:簡而言之,在順序隊列中,我們刪除元素,並沒有真正刪除,只是把front指針前進,那么兩個指針都往前,后面自然會空出許多單元,這樣就浪費了,我們采用環形隊列,在邏輯上把一個數組掰彎,形成一個圓,讓rear指到數組頂點之后可以回過頭來,再次指向最開始的單元,這樣就可以利用那些空間;

環形隊列通常約定進隊時少用一個數據元素空間,隊滿條件:(q->rear+1)% MaxSize == q->front  ;隊空條件:q->rear == q->front  ;

隊中元素個數:(rear-front+MaxSize)% MaxSize   ;

**********************************************************************

題目來了:火車軌道重排 

 

問題分析:分析題目意思我們可以大致得到,我們需要利用緩沖軌導,實現對車廂的排序。車廂排序有這樣的特點,首先是,車廂數從1-n,是連續的數字,其次我們需要按照從小到大的順序,一個一個的輸出,可供我們選擇緩沖軌道,但是,假設如果我現在車廂數目改變,或者說車廂數字順序改變,那我們相應的,所需要的軌道數數目也可能改變。我設計了一個動態的軌道數目來解決這個問題。首先需要按照合適的格式,把我們需要重排的車廂數序列放入隊列中,之后逐步的輸出車廂數。即先考慮主軌,如果主軌不能(主軌目前可以輸出的數字不是我想要的),那便考慮緩沖軌道,如果緩沖軌道也不能,那就是說明,我們需要的車廂,還在主軌的后邊,我們便需要把主軌的前面的車廂分散進入緩沖軌道,以此實現輸出。

 1 void Rearrangment_Queue(Queue *& Q, int G_number) {
 2     int nowOut = 1, i, temp, Sign;            // 緩沖軌導數標記 G_number 
 3     Queue ** kq = new Queue *[G_number];    // 數組指針 
 4     for (i = 0; i < G_number; i++)
 5         Initialize_Queue(kq[i], Q->number);    // 緩沖軌導初始化 
 6     while (nowOut <= Q->number) {        // 入軌判斷 
 7         Sign = 0;                            // 標記符Sign
 8         if (Empty_Queue(Q) && Q->data[Q->front + 1] == nowOut) {
 9             cout << nowOut << " ";
10             nowOut++;
11             Q->front++;
12             Sign++;                            // 標記符Sign
13         }
14         for (i = 0; i < G_number; i++)    // 緩沖軌判斷 
15             if (Empty_Queue(kq[i]) && kq[i]->data[kq[i]->front + 1] == nowOut) {
16                 cout << nowOut << " ";        // 緩沖軌非空(1)情況下進行匹配 
17                 nowOut++;
18                 kq[i]->front++;
19                 Sign++;                        // 標記符Sign
20             }
21         if (!Sign) {                    // 緩沖軌生成    
22             int j = 0;
23             while (Q->data[Q->front + 1] != nowOut) {
24                 Out_Queue(Q, temp);
25                 if (kq[j]->data[kq[j]->rear] < temp)
26                     Enter_Queue(kq[j], temp);
27                 else                        // 同G_number
28                     Enter_Queue(kq[++j], temp);
29             }
30         }
31     }
32     cout << endl;
33     for (i = 0; i < G_number; i++)            // 緩沖軌刪除
34         Destroy_Queue(kq[i]);
35     delete [] kq;
36 }

kq用來存放若干個緩沖軌,nowOut是目前需要輸出的數字;

先處理主軌,再處理緩沖軌,最后,若均沒有對應數字,則需要完成主軌和緩沖軌數字的變換;

當然還需要很多其余隊列相關函數:初始化、銷毀、進隊、出隊、判空以及創建隊列和G_number求解;

  1 #include<iostream>
  2 #include<cstdlib>
  3 
  4 using namespace std;
  5 
  6 struct Queue {
  7     int * data;
  8     int number;            // 車箱數 
  9     int front, rear;
 10 };
 11                         // 初始化
 12 void Initialize_Queue(Queue *& Q, int number) {    
 13     Q = (Queue *)malloc(sizeof(Queue));
 14     Q->number = number;            // 車廂數固定
 15     Q->data = new int[Q->number];
 16     Q->data[0] = 0;                // 確保后序判斷需要
 17     Q->front = Q->rear = -1;
 18 }
 19                         // 銷毀
 20 void Destroy_Queue(Queue *& Q) {
 21     delete[] Q->data;
 22     free(Q);
 23 }
 24                         // 進隊
 25 void Enter_Queue(Queue *& Q, int e) {
 26     Q->rear++;
 27     Q->data[Q->rear] = e;
 28 }
 29                         // 出隊
 30 void Out_Queue(Queue *& Q, int & e) {
 31     Q->front++;
 32     e = Q->data[Q->front];
 33 }
 34                         // 判空
 35 bool Empty_Queue(Queue * Q) {        // 空 = 0 ,非空 = 1
 36     return (!(Q->front == Q->rear));     
 37 }
 38                         // 創建以及G_number
 39 int Create_Queue(Queue *& Q) {
 40     int i, e, G_number = 0;        // 緩沖軌導數
 41     cout << "請輸入待重排的車廂序列 :";
 42     Q->rear = Q->number - 1;
 43     for (i = Q->number; i > 0; i--) {
 44         cin >> e;
 45         Q->data[i - 1] = e;
 46         if (i < Q->number && Q->data[i - 1] > Q->data[i])
 47             G_number++;            // 按最大所需軌道數計算
 48     }                            // 可能實際所需軌道數少於此數
 49     return G_number;            // 但是方便
 50 }
 51 
 52 void Rearrangment_Queue(Queue *& Q, int G_number) {
 53     int nowOut = 1, i, temp, Sign;            // 緩沖軌導數標記 G_number 
 54     Queue ** kq = new Queue *[G_number];    // 數組指針 
 55     for (i = 0; i < G_number; i++)
 56         Initialize_Queue(kq[i], Q->number);    // 緩沖軌導初始化 
 57     while (nowOut <= Q->number) {        // 入軌判斷 
 58         Sign = 0;                            // 標記符Sign
 59         if (Empty_Queue(Q) && Q->data[Q->front + 1] == nowOut) {
 60             cout << nowOut << " ";
 61             nowOut++;
 62             Q->front++;
 63             Sign++;                            // 標記符Sign
 64         }
 65         for (i = 0; i < G_number; i++)    // 緩沖軌判斷 
 66             if (Empty_Queue(kq[i]) && kq[i]->data[kq[i]->front + 1] == nowOut) {
 67                 cout << nowOut << " ";        // 緩沖軌非空(1)情況下進行匹配 
 68                 nowOut++;
 69                 kq[i]->front++;
 70                 Sign++;                        // 標記符Sign
 71             }
 72         if (!Sign) {                    // 緩沖軌生成    
 73             int j = 0;
 74             while (Q->data[Q->front + 1] != nowOut) {
 75                 Out_Queue(Q, temp);
 76                 if (kq[j]->data[kq[j]->rear] < temp)
 77                     Enter_Queue(kq[j], temp);
 78                 else                        // 同G_number
 79                     Enter_Queue(kq[++j], temp);
 80             }
 81         }
 82     }
 83     cout << endl;
 84     for (i = 0; i < G_number; i++)            // 緩沖軌刪除
 85         Destroy_Queue(kq[i]);
 86     delete [] kq;
 87 }
 88 
 89 int main()
 90 {
 91     Queue * Q;
 92     int G_number, number;
 93     cout << "請輸入最大車廂數 number :";
 94     cin >> number;
 95     Initialize_Queue(Q, number);
 96     G_number = Create_Queue(Q);
 97     cout << "火車車廂重排后 :";
 98     Rearrangment_Queue(Q, G_number);
 99     Destroy_Queue(Q);
100     return 0;
101 }
View Code

對於這樣一個問題似乎也可以修改為一個利用隊列進行排序的算法,但是對於空間方面的要求着實過大,理論上感覺還是可以的;

2020-05-25


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM