zoukankan      html  css  js  c++  java
  • 火车车厢重排——队列实现

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

  • 相关阅读:
    31 把数组排成最小的数 + 仿函数的写法就记忆这个就行了
    30 整数中1出现的次数(从1到n整数中1出现的次数)这题很难要多看*
    29 连续子数组的最大和
    c/c++ struct的大小以及sizeof用法
    28 最小的K个数
    27 数组中出现次数超过一半的数字
    26 字符串的排列
    Python 实例2—购物车
    python_threading模块实现多线程详解(转)
    Ubuntu 16.04 安装Postman
  • 原文地址:https://www.cnblogs.com/2015-16/p/12961440.html
Copyright © 2011-2022 走看看