火车车厢重排——队列实现
作者:互联网
其实队列和栈挺像的,所以也就没有单独写一个实现队列的笔记,可以参考一下栈的实现: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