合并两个有序数组,要求时间复杂度为O(n),且只要到O(1)的辅助空间

i= 0表示有序数组arr1的首元素,j = 未知,表示有序数组arr2的首元素
①首先比较第一个有序数组arr1和第二个有序数组arr2第一个元素的大小
如果arr1[i] < arr[j],i++
否则 index记住j的位置,index就是j变化之前的位置
②如果arr2[j] < arr[i],证明后面的元素小于后面的元素,需要进行往前的置换,所以j++,但是要保证j++不能越界
③进行了①和②之后,已经找到了需要置换两个数组的范围,使用swap交换
④进行i下标的更新,因为i+j-index已经排序好了,所以i要加上j-index
⑤直到while(i < j &&j < 数组的长度)不成立,程序结束
这里写图片描述

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

template <typename CONT>
void reverse(CONT &arr, int begin, int end)
{
    for (int i = 0; i < (end - begin + 1) / 2; i++)
    {
        auto temp = arr[begin + i];
        arr[begin + i] = arr[end - i];
        arr[end - i] = temp;
    }
}

template<class CONT>
void swap(CONT &a, int left, int middle, int right)
//三次翻转,就可以转换两个位置数组
{
    reverse(a, left, middle - 1);
    reverse(a, middle, right - 1);
    reverse(a, left, right - 1);
}

template <class CONT>
void merge_twoarray(CONT &arr, int arr2_begin)
{
    int i = 0;
    int j = arr2_begin;
    int index;

    while (i < j && j <= arr.size())
    {
        while (arr[i] < arr[j])
            i++;
        index = j;
        while (arr[j] < arr[i] && j != arr.size())
        {
            j++;
        }
        // rotate(arr.begin() + i, arr.begin() + index, arr.begin() + j);
        //库函数可以代替swap
        swap(arr, i, index, j);
        i += j - index;
    }
}
int main()
{
    vector<int> arr{1, 3, 5, 7, 9, 2, 4, 6, 8, 10};
    int arr2_begin;
    cout << "请输出数组2的起始位置:";
    cin >> arr2_begin;
    merge_twoarray(arr, arr2_begin);
    for (int i : arr)
        cout << i << " ";

    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37787222/article/details/79859388