zoukankan      html  css  js  c++  java
  • 归并排序-就地排序

    题目要求:对归并排序进行修改,要求合并过程的空间复杂度为O(1)

    解题思路:

    假设a[beg, mid]和b[mid+1,end]是两段有序的子段,分别记做A和B,现要对其进行合并

    1) 首先对A进行搜索,找到比B[0]大的第一个位置,记录为i,即A[0~i-1] < B[0],而A[i] > B[0];

    2) 对B进行搜索,找到大于A[i]的第一个位置,记录为j,则B[0~j-1]<B[i]

    3) 将A[i,mid], B[0,j-1] 进行旋转,使得B[0,j-1]旋转到左边,得到B[0,j-1] A[i, mid]

    4)A[i, mid] B[j, end]是原来问题的一个子问题,继续上述1)-3)的步骤

    下面是具体实现的代码:

      1 #include <iostream>
      2 
      3 using namespace std;
      4 
      5  
      6 
      7 void reverse(int *array, int beg, int end)
      8 
      9 {
     10 
     11     while(beg < end)
     12 
     13     {
     14 
     15         int tmp = array[beg];
     16 
     17         array[beg] = array[end];
     18 
     19         array[end] = tmp;
     20 
     21         ++beg;
     22 
     23         --end;
     24 
     25     }
     26 
     27 }
     28 
     29  
     30 
     31 void rotate(int *array, int beg, int end, int len)
     32 
     33 {
     34 
     35     len = len % (end - beg + 1);
     36 
     37     reverse(array, beg, end - len);
     38 
     39     reverse(array, end - len + 1, end);
     40 
     41     reverse(array, beg, end);
     42 
     43 }
     44 
     45  
     46 
     47 void merge(int *array, int beg, int mid, int end)
     48 
     49 {
     50 
     51     int i = beg;
     52 
     53     int j = mid + 1;
     54 
     55     while(i <= end && j <=end && i < j)
     56 
     57     {
     58 
     59         while(i <= end && array[i] < array[j])
     60 
     61         {
     62 
     63             ++i;
     64 
     65         }        
     66 
     67         int k = j;
     68 
     69         while(j <= end && array[j] < array[i])
     70 
     71         {
     72 
     73             ++j;
     74 
     75         }        
     76 
     77         if(j > k)   // 注意这个条件
     78 
     79         {
     80 
     81             rotate(array, i, j-1, j-k);
     82 
     83         }
     84 
     85         
     86 
     87         i += (j -k + 1);
     88 
     89     }
     90 
     91 }
     92 
     93  
     94 
     95 void mergeSort(int *array, int beg, int end)
     96 
     97 {
     98 
     99     if(beg == end)
    100 
    101         return;
    102 
    103         
    104 
    105     int mid = (beg + end) >> 1;
    106 
    107     mergeSort(array, beg, mid);
    108 
    109     mergeSort(array, mid + 1, end);
    110 
    111     merge(array, beg, mid, end);
    112 
    113 }
    114 
    115  
    116 
    117 int main()
    118 
    119 {
    120 
    121     int array[] = {8, 7, 6, 5, 4, 3, 2, 1};
    122 
    123     int beg = 0;
    124 
    125     int end = sizeof(array) / sizeof(int) - 1;
    126 
    127     mergeSort(array, beg, end);
    128 
    129     
    130 
    131     for(int i=beg; i<=end; ++i)
    132 
    133     {
    134 
    135         cout << array[i] << " ";
    136 
    137     }
    138 
    139     cout << endl;
    140 
    141     
    142 
    143     return 0;
    144 
    145 }
  • 相关阅读:
    PTA L1-002 打印沙漏 (20分)
    音乐研究
    LeetCode 155. 最小栈
    LeetCode 13. 罗马数字转整数
    LeetCode 69. x 的平方根
    LeetCode 572. 另一个树的子树
    errno错误号含义
    僵尸进程和孤儿进程
    TCP和UDP相关概念
    图相关算法
  • 原文地址:https://www.cnblogs.com/shirley-ict/p/5158910.html
Copyright © 2011-2022 走看看