zoukankan      html  css  js  c++  java
  • 面试题:在O(1)空间复杂度范围内对一个数组中前后连段有序数组进行归并排序

    题目:数组al[0,mid-1]和al[mid,num-1]是各自有序的,对数组al[0,num-1]的两个子有序段进行merge,得到al[0,num-1]整体有序。要求空间复杂度为O(1)。注:al[i]元素是支持'<'运算符的。

    分析

    代码实例:

    View Code
    #include<iostream>
    #include<stdlib.h>
    #include<stack>
    using namespace std;
    
    
    void MergeSort(int arry[],int len)
    {
        int left=0;
        int mid=len/2;
        int right=mid;
        while(left<mid&&right<len)
        {
            if(arry[left]<arry[mid])
                left++;
            else if(arry[left]>arry[mid])
            {
                while(arry[right]<arry[left])
                    right++;
                int temp=arry[left];
                arry[left]=arry[mid];
                for(int i=mid+1;i<right;i++)
                {
                    arry[i-1]=arry[i];
                }
                arry[right-1]=temp;
            }
        }
    }
    
    void PrintArry(int arry[],int len)
    {
        for(int i=0;i<len;i++)
            cout<<arry[i]<<" ";
        cout<<endl;
    }
    
    void main()
    {
        int arry[]={1,3,5,7,2,4,6,8};
        int len=sizeof(arry)/sizeof(int);
        PrintArry(arry,len);
    
        MergeSort(arry,len);
        PrintArry(arry,len);
    
        system("pause");
    }

    新的解体思路

    设定两个指针left和right,初始状态下分别指向两个排序数组的首元素,

    然后比较a[left]和a[right]大小,

    1. 如果a[left]<=a[right],那么数组中元素位置不发生改变,然后left往前进一步。
    2. 如果a[left]>a[right],则表明前半段元素中存在大于后半段的元素,那么我们将后半段这个小的元素移到前半段来。但是在移动之前,我们得为这个元素空留出地方。这就有了元素移动的操作。比如{1,3,5,7,2,4,6,8,10}这样子序列,我们发现后半段的2小于前半段的3,那么我们将2放入临时变量temp中,然后将{3,5,7}往后移动一个位置,然后将空出来的位置放入temp的值。
    3. 这里总体的循环是while(left<right&&right<len)

    代码实现

    View Code
    void mergesort2(int arry[],int len)
    {
        int mid=len/2;
        int left=0;
        int right=mid;
    
        while(left<right&&right<len)
        {
            int temp;
            if(arry[left]<=arry[right])
            {
                left++;
            }
    
            else
            {
                temp=arry[right++];
                for(int i=right-1;i>left;i--)
                {
                    arry[i]=arry[i-1];
                }
                arry[left]=temp;
            }
    
            PrintArry(arry,len);
            cout<<left<<" "<<right<<endl;
        }
    }

    上面程序的输出结果是

    View Code
    1 3 5 7 2 4 5 8 10
    1 4
    1 2 3 5 7 4 5 8 10
    1 5
    1 2 3 5 7 4 5 8 10
    2 5
    1 2 3 5 7 4 5 8 10
    3 5
    1 2 3 4 5 7 5 8 10
    3 6
    1 2 3 4 5 7 5 8 10
    4 6
    1 2 3 4 5 7 5 8 10
    5 6
    1 2 3 4 5 5 7 8 10
    5 7
    1 2 3 4 5 5 7 8 10
    6 7
    1 2 3 4 5 5 7 8 10
    7 7
  • 相关阅读:
    openssl生成公钥私钥对 加解密
    boost replace_if replace_all_regex_copy用法
    PS 图像滤镜— — USM 锐化
    使用boost库生成 随机数 随机字符串
    改动Android设备信息,如改动手机型号为iPhone7黄金土豪版!
    验证(Verification)与确认(Validation)的差别
    Spring-SpringMVC-Hibernate整合
    全面整理的C++面试题
    Metropolis Hasting算法
    捕捉到来自宇宙深空的神奇X-射线信号
  • 原文地址:https://www.cnblogs.com/xwdreamer/p/2490343.html
Copyright © 2011-2022 走看看