原地归并排序--2013-06-02


问题描述:数组a[n],a[0]~a[m]和a[m+1]~a[n-1]两个子数组分别是有序的,其中m<n-1。要求在O(n)的时间复杂度和O(1)的空间复杂度内使整个数组有序。


源地址:http://www.geeksforgeeks.org/forums/topic/amazon-interview-question-for-software-engineerdeveloper-about-algorithms-arrays-28/


我的思路:由于要求使用O(1)的空间,所以只能依靠交换来实现排序。在数组中央开辟临时数组,存放因交换而产生的数据,这个临时数组也是有序的,举例如下:


n = 9, m = 3

3    4     10     12     5    6     8     9     11  

a[0]与a[4]比较,无需交换,继续

a[1]与a[4]比较,无需交换,继续

a[2]与a[4]比较,需要交换:

3451210,6,8911

此时临时数组为a[4]这一个元素,我们继续比较

a[3], a[4], a[5]比较,a[3]与a[5]交换,临时数组元素增为两个a[4]与a[5]:

345610,12,8,911

a[4], a[4], a[6]比较,需要交换,同时临时数组指向a[6],且只有一个a[6]元素:

34568,12,10,911

a[5], a[6], a[7]比较,a[5]与a[7]交换,临时数组此时为a[6]和a[7]:

34568,9,10,1211

a[6], a[6], a[8]比较,无需交换,可以认为此时临时数组清空

a[7], a[8]比较,交换

34568,9,10,1112

排序结束


程序如下(未验证):

#include<iostream>

using namespace std;

void swap(int& value1, int& value2);
int compare(int value1, int index1, int value2, int index2);
int compare(int value1, int index1, int value2, int index2, int value3, int index3);

int main() {
    int *a, n, m, i;
    cin>>n>>m;
    a = new int[n];
    for (i=0; i<n; i++) {
        cin>>a[i];
    }
    int pre_start=0, pre_end=m-1, tmp_start=-1, tmp_end=-1, suf_start=m, suf_end=n-1;
    int tmp_index=0, tmp_value=0, min_index=-1;
    bool swap_need=0;
    while (suf_start<suf_end) {
        if (pre_start == tmp_start || tmp_start==-1) {
            min_index = compare(a[pre_start], pre_start, a[suf_start], suf_start);
            if (min_index != pre_start) {
                swap(a[pre_start], a[suf_start]);
                tmp_start = tmp_end = suf_start;
                pre_start ++;
                suf_start ++;
            } else {
                pre_start ++;
            }
        } else {
            min_index = compare(a[pre_start], pre_start, a[tmp_start], tmp_start, a[suf_start], suf_start);
            if (min_index == pre_start) {
                pre_start ++;
            } else if (min_index == tmp_start) {
                swap(a[pre_start], a[tmp_start]);
                pre_start ++;
            } else if (min_index == suf_start) {
                swap(a[pre_start], a[suf_start]);
                pre_start ++;
                suf_start ++;
            }
        }
    }
    return 0;
}

void swap(int& value1, int& value2) {
    int tmp = value1;
    value1 = value2;
    value2 = tmp;
}

int compare(int value1, int index1, int value2, int index2) {
    if (value1>value2) return index2;
    else return index1;
}

int compare(int value1, int index1, int value2, int index2, int value3, int index3) {
    if (value1>value2) {
        if (value2>value3) return index3;
        else return index2;
    } else {
        if (value1>value3) return index3;
        else return index1;
    }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值