C语言练习|合并两个有序数组

题目

给你两个按非递减顺序排列的整数数组nums1 和nums2(都是有序的),另有两个整数m 和n ,分别表示 numsl 和nums2 中的元素数目。请你合井 nums2到nums1 中,使合并后的数組同样按 非递减顺序排列。注意:最終,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m+n,其中前 m个元素表示应合并的元素,后n个元素为 0,应忽略。 nums2 的长度为n。

分析图示

文字解析:

这段代码实现了合并两个有序数组的功能。它使用了三个指针end1、end2和end来分别指向nums1、nums2和合并后的结果数组nums1的末尾。

首先,我们初始化指针end1为nums1的最后一个元素的索引,指针end2为nums2的最后一个元素的索引,指针end为合并后的结果数组nums1的最后一个位置的索引。

然后,我们使用一个循环来比较nums1和nums2中的元素,并将较大的元素放入合并后的结果数组nums1的末尾。每次比较后,我们将相应的指针向前移动一位,并将结果存储在合并后的结果数组的当前位置。直到其中一个数组的元素全部被合并完。

接下来,如果nums2中还有剩余的元素,我们将它们依次放入合并后的结果数组nums1的剩余位置。

最后,合并完成后,nums1中就存储了合并后的有序数组。

在完成这段代码之前,需要注意以下几点:

1. 确保nums1和nums2是按非递减顺序排列的,否则合并后的结果可能不是有序的。
2. 确保nums1的长度足够大,能够容纳合并后的结果。即nums1的长度应为m+n。
3. 在合并过程中,我们是从后往前遍历数组,因此需要确保nums1和nums2中的元素都在有效的索引范围内。
4. 如果nums1和nums2的长度为0,或者其中一个数组的长度为0,那么不需要进行合并操作,直接返回即可

示例代码

void merge(int* nums1, int m, int* nums2, int n) {
    int i = m - 1;
    int j = n - 1;
    int k = m + n - 1;
    
    while (i >= 0 && j >= 0) {
        if (nums1[i] > nums2[j]) {
            nums1[k] = nums1[i];
            i--;
        } else {
            nums1[k] = nums2[j];
            j--;
        }
        k--;
    }
    
    while (j >= 0) {
        nums1[k] = nums2[j];
        j--;
        k--;
    }
}

题外话

strncpy函数

strncpy函数是C语言中的字符串处理函数,用于将一个字符串的一部分复制到另一个字符串中。它的函数原型如下:

char* strncpy(char* destination, const char* source, size_t num);

注意:此函数是运用于字符串数据类型的。 

qsort函数和memcpy函数的结合运用

qsort函数

qsort函数是一个标准库函数,用于对数组进行快速排序。它的函数原型如下:

void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
  • base:指向要排序的数组的指针。
  • nmemb:数组中元素的个数。
  • size:每个元素的大小(以字节为单位)。
  • compar:比较函数的指针,用于指定元素之间的比较规则。
比较函数compar的原型如下: 
int compar(const void *a, const void *b);

比较函数接受两个指向元素的指针,并返回一个整数值,表示两个元素的大小关系。返回值的含义如下:

  • 小于0:表示a小于b。
  • 等于0:表示a等于b。
  • 大于0:表示a大于b。

qsort函数会根据比较函数的返回值对数组进行排序。排序是原地进行的,即不会创建新的数组,而是直接修改原数组。 

使用: 
#include <stdio.h>
#include <stdlib.h>

int compare(const void *a, const void *b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int arr[] = {5, 2, 8, 1, 9};
    int n = sizeof(arr) / sizeof(arr[0]);

    qsort(arr, n, sizeof(int), compare);

    printf("Sorted array: ");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

memcpy函数

memcpy函数是一个标准库函数,用于在内存之间进行字节级别的拷贝。它的函数原型如下:

void *memcpy(void *dest, const void *src, size_t n);
  • dest:指向目标内存区域的指针,即拷贝的目的地。
  • src:指向源内存区域的指针,即拷贝的来源。
  • n:要拷贝的字节数。

memcpy函数将源内存区域的内容拷贝到目标内存区域中,拷贝的字节数由参数n指定。拷贝过程是按字节进行的,不会考虑数据类型。 

综合使用

代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void merge(int* nums1, int m, int* nums2, int n) {
    // 将nums2拷贝到nums1的后面
    memcpy(nums1 + m, nums2, n * sizeof(int));

    // 对nums1进行排序
    qsort(nums1, m + n, sizeof(int), compare);
}

int compare(const void* a, const void* b) {
    return (*(int*)a - *(int*)b);
}

int main() {
    int nums1[6] = {1, 2, 3, 0, 0, 0};
    int nums2[3] = {2, 5, 6};
    int m = 3;
    int n = 3;

    merge(nums1, m, nums2, n);

    printf("Merged array: ");
    for (int i = 0; i < m + n; i++) {
        printf("%d ", nums1[i]);
    }
    printf("\n");

    return 0;
}

缺点:由于qsort函数是使用快速排序算法实现的,其平均时间复杂度为O(nlogn),其中n是nums1数组和nums2数组的总长度。虽然这个时间复杂度在大多数情况下是可以接受的,但在某些情况下可能会比较耗时。

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C肆absolute security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值