把两个数组合并

①将两个整型升序数据集合A和B合并成一个升序数据集合
例A={3,5,7,8,9,12,16} B={2,4,7,9,11}
结果:C={2,3,4,5,7,7,8,9,9,11,12,16}

#include<stdio.h>
#define M 7
#define N 5

#主函数
int main(void)
{
     int a[M]={3,5,7,8,9,12,16};
     int b[N]={2,3,4,5,7,7,8,9,9,11,12,16};
     int c[M+N];
     Merge(a,b,c);
     for(int i = 0;i < M+N;++i){
         printf("5%d\n",c[i]);
     }
     return 0;
}

方法一:

void Merge(int a[],int b[],int c[]){
    int i= 0 , j = 0,k = 0;
    while(i<M && j<N){//总哟一个先结束存放,或者是a或者是b
         if(a[i]>b[j]){
             c[k++] = b[j++];
         }else{
             c[k++] = a[i++];
         }
         if(i<M){//a没有存放完
             while(i<M){
                 c[k++] = a[i++];
             }
         }else{//b没有存放完
              while(j<N){
                 c[k++] = b[j++];
              }
         }
    }
}

此方法是同时遍历数组a和数组b,取到数组a和b中的元素,分别进行比较,把较小的那一个存放在数组c中,然后继续取元素,继续比较,依次循环,总有一个数组先存放完,以此为循环条件。出循环后判断是哪个数组先完成了存放,然后把未完成存放的继续进行遍历,存入数组c。

方法二:
void Merge(int a[],int b[],int c[]){
   int i = 0,j = 0,k = 0;
   int *s,t,len;
   while(i<M && j<N){
       if(a[i]>b[j]){
           c[k++] = b[j++];
       }else{
           c[k++] = a[i++]; 
       }
       if(i<M){//a没有存放完
           s = a;
           t = i;
           len = M;
       }else{//b没有存放完
           s = b;
           t = j;
           len = N;
       }
       while(t<len){
           c[k++] = s[t++];
       }
   }
}

//改进,也可以不用变量t
void Merge(int a[],int b[],int c[]){
   int i = 0,j = 0,k = 0;
   int *s,len;
   while(i<M && j<N){
       if(a[i]>b[j]){
           c[k++] = b[j++];
       }else{
           c[k++] = a[i++]; 
       }
       if(i<M){//a没有存放完
           s = a;
           len = M;
       }else{//b没有存放完
           s = b;
           i = j;
           len = N;
       }
       while(t<len){
           c[k++] = s[t++];
       }
   }
}

此方法利用指针s指向没有存放完的数组的元素,这样就可以把方法一中的while语句提出来,提高效率。

方法三:
void Merge(int a[],int b[],int c[]){
    int i = 0,j = 0,k = 0;
    int *s=a,len = M;
    while(i<M  && j<N){
        if(a[i]>b[j]){
            c[k++] = b[j++];
        }else{
            c[k++] = a[i++];
        }
        if(j<N){
             s = b;
             i = j;
             len = N;
        }
        while(i<len){
             c[k++] = s[i++];
        }
    }
}

思路:此方法是在方法二的基础上,开始时就假设数组a没有存放完,然后在后面对数组b没有存放完的情况进行判断,如果数组b没存放完则对指针s以及长度len进行改变。简化了代码。

方法四:
void Merge(int a[],int b[],int c[]){
    int i = 0,j = 0,k = 0;
    while(i<M || j<N){
        if(j>N || i<M && a[i] < b[j]){//存放a
            c[k++] = a[i++];
        }else{
            c[k++] = b[j++];
        }
    }
}

思路:此方法代码量少,但是难懂。当数组a和数组b任何一个没有存放完时都继续操作,进行存放。此条件作为进循环的条件。循环里面进行到底是存放a还是存放b的操作。
存放a的条件:
b存放完了||b没存放完&&a没存放完 && a[i]<b[j] 时存放a
b存放完了||a没存放完 && a[i]<b[j] 时存放a
存放b的条件:
b没存放完&&a存放完了||b没存放完&&a[i]>b[j] 时存放b

  • 9
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值