原地归并排序变形

题目:给出一个数组,数组中的两半都是已知顺序的,现要实现将这个数组有序化,要求空间复杂度为 O(1),时间复杂度尽可能的小,编程实现!


#include <iostream>

using namespace std;
int arr[10] = { 1,3,5,7,9,2,4,6,8,10};

//交换数据
int swaparr(int &a,int &b)
{
    a=a+b;
    b=a-b;
    a=a-b;
}
void reversearr(int a[],int n)  //数组起始地址,数组长度
{
    int i,b;
    for(i=0,b=n-1;i<b;i++,b--)
        swaparr(a[i],a[b]);
}
void leftshift(int a[],int n,int i)//数组以a[0]为起始地址,长度为n,循环左移i位
{
    reversearr(a,i);
    reversearr(a+i,n-i);
    reversearr(a,n);
}
void mergesort(int a[],int n,int s)//数组,总元素,第二段的起始地址
{
    int mid = s;//记录第一段数组的最后一位
    int i,j;//两个移动指针
    i=0;
    j=s;
    while(true)
    {
        while(a[i]<=a[j] && i<mid)
            i++;
        while(a[j]<a[i] && j<n)
            j++;
        if(i >= mid)  //  出口1
            break;
        ///针对 i~j-1 位置的几个数实现循环左移 j-s位
        leftshift(a+i,j-i,mid-i);
        i=j-mid+i;//重新计算出 i 的位置
        //重新计算出mid的位置
        mid=j;
        if(mid>=n)        //出口2
            break;
    }
}

void print()
{
    int i=0;
    for(i=0;i<10;i++)
        cout<<arr[i]<<"  ";
    cout<<endl;
}
int main()
{
    cout << "Hello world!" << endl;
    print();
    mergesort(arr,10,5);
    print();
    return 0;
}


说明:

此处由于要求空间复杂度为O(1),不能使用另开辟空间的归并排序实现,这里我们需要在原有数组中实现归并排序,原地归并排序;

首先,我们很容易理解到可以使用插入排序的方法将 数组后半段数据通过插入排序使整个数组归并在一起;这个最坏情况下的时间复杂度是O(n2);

比如 {6,7,8,9,10,1,2,3,4,5};这个数组将后5个使用插入排序的话时间复杂度为O(n2);为了解决这种情况,次我们提出了更好的解法:

对于数组arr[10] ,两半的起始指针分别为 i,j;如上程序代码理解~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值