[剑指Offer学习] 面试题:有序数组的合并

题目描述

有两个排序的数组A1和A2,内存在A1的末尾有足够的空余空间容纳A2。请写一个函数,把A2的所有数字插入A1中,并且所有的数字是排序的。

规律发现

首先想到的思路是从A1从头到尾复制数字,但是就会出现多次复制一个数字的情况。
更好的办法是从尾到头比较A1和A2的数字,并把较大的数字,复制到A1中的合适位置。
由于在Java中不能像C++中那样定义一个指定大小的数组:int A[100] = {};而且,int数组不能够自己动态扩充容量,因此,为了避免程序中出现数组越界的错误,在用java实现该算法时,需要重新定义一个数组A3,用于存放合并之后的数组元素。

完整代码展示

1、java实现

public class N2同类型两个排序的数组合并 {
    public static void merge(int A1[],int[] A2,int A3[]){
        //所有的字符串的尾部都会有一个'\0'字符,所以实际存储的尾部是字符串长度-1
        int indexA1 = A1.length-1;
        int indexA2 = A2.length-1;
        //A1和A2合并后的字符串长度
        int indexA3 = A3.length-1;

        //比较A1和A2尾部的字符,直到indexA1或indexA2移动到最前面
        while(indexA1 >= 0 && indexA2 >= 0 && indexA3 >=0){
//        for(int indexMerged1 = indexMerged;indexMerged1>=0;indexMerged1--){
            //如果A1尾部的数字大于A2尾部的数字,将A1中的数复制到对应的位置
            //并且向前移动indexMerged和indexA1
            if(A1[indexA1] >= A2[indexA2]){
                A3[indexA3] = A1[indexA1];
                indexA3--;
                indexA1--;
            }
            //如果A1尾部的数字小于A2尾部的数字,将A1中的数复制到对应的位置
            //并且向前移动indexMerged和indexA2
            else{
                A3[indexA3] = A2[indexA2];
                indexA3--;
                indexA2--;
            }
        }

        //A2的第一个数字比A1的indexA1位置处的数字还要小
        //这一次的移动之后A2全部复制完
        while (indexA1 >= 0) {
            A3[indexA3] = A1[indexA1];
            indexA3--;
            indexA1--;
        }

        //A2的第一个数字比A1的indexA1位置处的数字要大
        //这一次的移动之后A1全部复制完
        while(indexA2 >= 0){
            A3[indexA3] = A2[indexA2];
            indexA3--;
            indexA2--;
        }
    }

    public static void main(String[] args) {
        //待合并数组A1和A2
        int[] A1={1,3,5,8};
        int[] A2 = {2,3,4,9};
        //数组A3用来存放合并之后的数组
        int[] A3 = new int[A1.length+A2.length];
        merge(A1,A2,A3);
        for(int i=0;i<A3.length;i++){
            System.out.println(A3[i]);
        }
    }
}

2、C++实现

#include<iostream>
using namespace std;
const int MaxArray = 100;

void Combine_Array(int A[MaxArray+1],int B[],int alen,int blen)
{
    int i = alen - 1;//j指向A的最后一个元素
     int j = blen - 1;//i指向B的最后一个元素
     for (int k = alen + blen - 1; k >= 0; k--)//从后往前插入
     {
         if (A[i] > B[j]){//选择较大的依次放在尾部
            A[k] = A[i];
            --i;
         }
      else{
           A[k] = B[j];
           j--;
       }
       while (i < 0&&j>=0){//如果B剩余,则把B中的剩余元素依次移动到A的前端;若A剩余则证明已经排好
          A[k] = B[j];
          --j;
       } 
   }
   for (int i = 0; i < alen+blen; i++)//打印出合并后的数组
   {
       cout << A[i] << "    ";
   }
   cout << endl;
}
int main()
{
    int A[MaxArray+1] = { 1, 3, 5, 7, 8, 12 };
    int B[] = { 13, 15, 16, 20 };
    Combine_Array(A, B, 6, 4);
    system("pause");
    return 0;
}

运行结果显示

C++实现结果
Java实现结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值