利用分治法来求两个排序数组的中位数

有两个数组 ar1[] 和ar2[] 两个数组的长度都为n
求ar1[]和ar2[]的中位数
可以借鉴归并排序的思想 实质上就是将将两个已经排好序的数组 合并成一个数组 的过程只是在这个过程中添加了一个计算从小到大的次序的数
(count ) 当count =n 和n+1时记录下这两个数 然后在这两个数中间取平均值 就可以了 但是这个算法的复杂度是o(n)

如果我们想达到log(n)的复杂度的话 则可以用分治法来实现

求出 ar1[]的中位数 m1 ar2[]的中位数 m2
1.如果m1==m2 则返回m1就可以了
2.如果m1>m2 则取ar1[]中的前半部分和 m2中的后半部分 作为新的数组
3.如果m1

int median(int arr[], int n)
{
    if (n%2 == 0)
        return (arr[n/2] + arr[n/2-1])/2;
    else
        return arr[n/2];
}

int getMedian(int ar1[], int ar2[], int n) {
    int m1;
    int m2;
    if (n <= 0)
        return -1;
    if (n == 1)
        return (ar1[0] + ar2[0]) / 2;

    if (n == 2)
        return (max(ar1[0], ar2[0]) + min(ar1[1], ar2[1])) / 2;

    m1 = median(ar1, n);
    m2 = median(ar2, n);
    /* 相等可直接返回 */
    if (m1 == m2)
        return m1;
    if (m1 < m2) {
        if (n % 2 == 0)
            return getMedian(ar1 + n/2-1, ar2, n/2 + 1);
        else
            return getMedian(ar1 + n/2, ar2, n/2+1);
    } else {
        if (n % 2 == 0)
            return getMedian(ar2 + n/2-1, ar1, n/2+1);
        else
            return getMedian(ar2 + n/2, ar1, n/2+1);
    }
}

int main()
{
    int ar1[] = {1, 12, 10, 26, 38};
    int ar2[] = {2, 13, 17, 30, 45};

    int n1 = sizeof(ar1)/sizeof(ar1[0]);
    int n2 = sizeof(ar2)/sizeof(ar2[0]);
    if (n1 == n2)
        printf("Median is %d", getMedian(ar1, ar2, n1));
    else
        printf("Doesn't work for arrays of unequal size");
    return 0;
}
  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 分治法选择数组中的第k小元素的步骤如下: 1. 在数组中选择一个基准元素。 2. 将数组划分为小于基准元素、等于基准元素和大于基准元素的三个部分。 3. 如果第k小元素在小于基准元素的部分,则在这部分递归地查找第k小元素。 4. 如果第k小元素在等于基准元素的部分,则直接返回基准元素。 5. 如果第k小元素在大于基准元素的部分,则在这部分递归地查找第k-m小元素,其中m是等于基准元素的数量加上小于基准元素的数量。 ### 回答2: 分治法选择数组中的第k小元素的算法步骤如下: 1. 将原始数组划分为长度相等的子数组,直到每个子数组只包含一个元素。 2. 对每个子数组进行排序。 3. 从每个排序后的子数组中选择中位数(即元素个数为奇数时,选取中间的元素;元素个数为偶数时,选取中间两个元素的平均值)。 4. 将这些中位数构成一个新的数组作为中位数数组。 5. 递归地调用该算法,将中位数数组作为新的原始数组进行处理,直到中位数数组中只包含一个元素。 6. 找到中位数数组中的第k小元素,即为原始数组中的第k小元素。 这个算法基本上是利用分治法的思想。通过对原始数组进行划分,将大的问题分解为小的子问题,并将子问题的结果进行合并,在每一次划分和合并的过程中,选取合适的元素进行排序和选择,最终得到原始数组中的第k小元素。算法的时间复杂度为O(nlogn),其中n为原始数组的长度,因为每一次划分和合并都需要进行数组排序和复制操作。 ### 回答3: 分治法选择数组中的第k小元素的算法步骤如下: 1. 将给定的数组分成若干个子数组。 2. 对每个子数组进行递归地找到其中的中位数。 3. 将这些中位数组成一个新的数组,称为中位数数组。 4. 对中位数数组进行递归地找到其中的中位数,即中位数数组中位数。 5. 将中位数数组中位数作为枢纽(pivot)。 6. 根据枢纽将原始数组划分为三个部分,小于枢纽的元素、等于枢纽的元素和大于枢纽的元素。 7. 根据k与三个部分的大小关系,决定继续在哪个部分继续查找第k小元素。 - 如果k小于等于小于枢纽的元素的数量,则在小于枢纽的部分继续查找第k小元素。 - 如果k大于小于枢纽的元素的数量且小于等于小于枢纽加等于枢纽的元素的数量,则返回枢纽作为第k小元素。 - 如果k大于小于枢纽加等于枢纽的元素的数量,则在大于枢纽的部分继续查找第k小元素。 8. 重复递归进行上述步骤,直到找到第k小元素。 这个算法的关键在于每次选择合适的枢纽,以尽量均匀地划分数组,从而使得每次递归的规模下降得快。平均时间复杂度为O(n),最坏情况下的时间复杂度为O(n^2),其中n为数组的长度。这个算法在时间复杂度上比简单的排序算法如冒泡排序和插入排序更优秀,适合用于需要找到数组中第k小元素的场景。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值