其他分享
首页 > 其他分享> > 火车车厢重排——队列实现

火车车厢重排——队列实现

作者:互联网

其实队列和栈挺像的,所以也就没有单独写一个实现队列的笔记,可以参考一下栈的实现: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

标签:队列,number,Queue,++,kq,重排,front,data,火车车厢
来源: https://www.cnblogs.com/2015-16/p/12961440.html