• 中国大学MOOC-数据结构基础习题集、07-2、Insert or Merge


    题目链接:http://www.patest.cn/contests/mooc-ds/07-2

    题目分析:这是一道考察插入排序和归并排序的一道题。题目可能有点难以理解,这里稍加解释一下:

      首先,输入的第一行是一个整型数,代表数据的个数。第二行是起始数据,排序从这里开始。第三行是目标(或者叫终止)数据,排序到这里结束。我们知道插入排序和合并排序是有很大不同的,如果是目标数据(我们暂且这么叫)是由插入排序生成的,就输出Insertion Sort;如果是目标数据是由归并排序生成的,就输出Merge Sort。不管是何种输入,都要输出这种排序的“下一步”。注意这里的“下一步”是“一大步”,也就是“一趟”归并排序。

    特别说明:

      1. 首先推荐一个函数:inplace_merge函数。它的作用和merge函数差不多,只不过是在一个容器中进行归并。

      函数参数:inplace_merge(first,mid,last,compare); // 将[first,mid) 和 [mid,last)这两个区间进行归并成一个有序序列。

      有了这个可以不用自己写merge了。但是此处博主并没有用到它。这里只是教大家用C++的STL解决实际问题。使用使需要引头文件#include <algorithm>。

      如果相对merge类函数有更多了解,不妨阅读:http://www.cppblog.com/zhangyq/archive/2012/02/05/164060.html

      2. 刚才说到博主这里没有用到merge类的函数,是因为博主压根没有用“归并排序”。当时博主的最直接的想法就是用sort替代真实的MSort和Merge。所以算是偷懒吧。另外程序中有点了乱,有的地方

      3. 插入/合并排序可能出现一趟下来没有改变的情况,要输出有改变的才可以。也就是说你的输出不能和输入的第三行的那串数字相同。这点略坑。可以按照下面的方法测试下自己的代码。

    建议测试用例:

      测试用例一(这个没什么好说的,肯定都能过,为了与用例二比照):

    测试输入:
    10
    3 1 2 4 5 6 7 9 8 10
    1 3 2 4 5 6 7 9 8 10
     
    预期结果:
    Insertion Sort
    1 2 3 4 5 6 7 9 8 10  

      测试用例二(重点):

    测试输入:
    10
    3 1 2 4 5 6 7 9 8 10
    1 2 3 4 5 6 7 9 8 10
    预期结果:
    Insertion Sort
    1 2 3 4 5 6 7 8 9 10
    而不是:
    Insertion Sort
    1 2 3 4 5 6 7 9 8 10
    (和输入第三行一样了,是错的)

    代码分析:

      每个函数前面都有注释,相信大家都能看得懂。

      就像前面说的一样,博主只是用到了归并排序的思想,没有真正实现归并排序。想看归并排序的同学,可以看作业07-1,我刚刚更新了归并排序。这里我是借助了sort函数简化代码。这样做有点偷懒,但是却十分方便。

      顺便解释一下,为什么在主函数中有a和aa两个数组。这是因为在判断IsInsert中,已经把a数组改变了,所以需要一个备份。就是这样,喵~

      1 #include <iostream>
      2 #include <algorithm>
      3 
      4 #define NOTEXIST -1
      5 
      6 using namespace std;
      7 
      8 // 判断两个数组是否相等
      9 bool isEqual(int a[], int b[], int n)
     10 {
     11     for(int i=0; i<n; i++)
     12         if(a[i] != b[i])
     13             return false;
     14     return true;
     15 }
     16 
     17 // 进行插入排序的移动元素操作
     18 int moveElement(int i, int a[])
     19 {
     20     int tmp = a[i];
     21     int j;
     22     for(j=i; j>0 && a[j-1] > tmp; j--)
     23         a[j] = a[j-1];
     24     a[j] = tmp;
     25     return j;
     26 }
     27 
     28 // 判断是不是插入排序
     29 int isInsertSort(int a[], int b[], int n)
     30 {
     31     for(int i=0; i<n; i++)
     32     {
     33         moveElement(i, a);
     34         if(isEqual(a, b, n) == true)
     35             return i;
     36     }
     37     return NOTEXIST;
     38 }
     39 
     40 // 非递归算法
     41 bool MSort( int A[], int B[], int N )
     42 {
     43     int step = 1;
     44     bool myFlag = false;
     45     while(step < N)
     46     {
     47         step *= 2;
     48         for(int i=0; i<N; i=i+step)
     49         {
     50             int first = i;
     51             int last = first + step;
     52             if(last >= N)
     53                 last = N;
     54             sort(A+first, A+last);
     55         }
     56         if(myFlag == true)
     57         {
     58             // 如果已经成功,走完了归并排序之后直接返回即可!注意此if语句应该位于下一个if语句之前!!
     59             if(isEqual(A, B, N) == false)
     60                 return true;
     61         }
     62         if(isEqual(A, B, N) == true)
     63         {
     64             // 如果发现和目标数据相同,则置myFlag标识为true,代表已经成功,只需要再走一次归并排序即可!
     65             myFlag = true;
     66         }
     67     }
     68     return false;
     69 }
     70 
     71 // 输出数组内的元素
     72 void outputElement(int x[], int n)
     73 {
     74     for(int i=0; i<n; i++)
     75     {
     76         if(i != n-1)
     77             cout << x[i] << " ";
     78         else
     79             cout << x[i];
     80     }
     81     cout << endl;
     82 }
     83 
     84 int main()
     85 {
     86     int n;
     87     cin >> n;
     88     int *a = new int[n];
     89     int *aa = new int[n];
     90     for(int i=0; i<n; i++)
     91     {
     92         cin >> a[i];
     93         aa[i] = a[i];
     94     }
     95 
     96     int *b = new int[n];
     97     for(int j=0; j<n; j++)
     98         cin >> b[j];
     99     int IS = isInsertSort(a, b, n);
    100     if(IS != NOTEXIST)
    101     {
    102         cout << "Insertion Sort" << endl;
    103         while(isEqual(a, b, n) == true)
    104         {
    105             IS = moveElement(IS+1, a);
    106         }
    107         outputElement(a, n);
    108     }
    109     else
    110     {
    111         cout << "Merge Sort" << endl;
    112         MSort(aa, b, n);
    113         outputElement(aa, n);
    114     }
    115     return 0;
    116 }

    AC成果:

  • 相关阅读:
    git切换到指定分支,git新建分支与合并
    别克英朗更换空调滤网与发动机空气滤网
    杭州市浙A区域号牌正则表达式
    新史记·特斯拉怒怼民女传
    史记 袁隆平传
    抵押贷款国五车辆,非浙A(外地)转浙A(摇号),本人名下电子转籍流程
    // TPLINK WR882N/TL-WR842N管理脚本
    netsh用法
    百度AI车号牌照片识别
    .htaccess 301重定向 http https 多域名
  • 原文地址:https://www.cnblogs.com/clevercong/p/4222579.html
Copyright © 2020-2023  润新知