找两个有序数组中的中位数---分治法实验1

本文介绍了如何使用分治策略在O(log n)时间复杂度内找到两个有序数组的中位数。当两个数组中间元素相等时,中位数即为这两个元素;否则,通过比较调整查找范围。作者通过实例分析和代码实现详细阐述了这一算法,并给出了三组测试数据以覆盖所有情况。
摘要由CSDN通过智能技术生成

问题描述
设X[ 0 : n - 1]和Y[ 0 : n – 1 ]为两个数组,每个数组中含有n个已排好序的数。找出X和Y的2n个数的中位数。
编程任务
利用分治策略试设计一个O (log n)时间的算法求出这2n个数的中位数。
数据输入
由文件input.txt提供输入数据。文件的第1行中有1个正整数n(n<=200),表示每个数组有n个数。接下来的两行分别是X,Y数组的元素。
实现提示
比较两个序列的中位数大小,如果两个数相等,则该数为整个2n个数据的中位数,否则通过比较,分别减少两个序列的查找范围,确定查找的起止位置,继续查找。
结果输入输出
输入文件
在这里插入图片描述
输出文件在这里插入图片描述
①这道题下午想了有挺久,首先很容易想到如果两个数组中间两个数相等,那中位数就是中间那个数。这个可以举例,如果n是奇数,如果n是偶数,发现都是满足要求的。但是如果直接证的话,也得分如果n是奇数,那么a数组中中小于xa的有(n-1)/2个,大于xa的也有(n-1)/2个,同理b数组也是,所以对于xa或者是yb则整个2n数组中小于和大于他们的数分别为(n-1)个,取这两个数的平均值(xa+yb)/2=xa=yb即为中位数。n是偶数,也差不多这么证。
②但如果两个数组中间两个数不等的话,如果a数组中位数小于b数组中位数的话,那两个数组合并之后的中位数一定在a的右边或者b的左边我感觉这其实细细品一下就出来了,然后分奇偶再讨论一下,或者举出实例,在n是奇数或是偶数的时候该怎么分。感觉举实例是最容易理解的
③如果a数组中位数大于b数组中位数的话,就跟第二种情况相反了~

#include <stdio.h>
#include <stdlib.h>
int a[200],b[200];
double FindOneMiddle(int a[],int left,int right)
{
   
    double mid;
    int n=right-left+1;
    if(n%2==0)//有偶数个元素
        mid=(a[n/2]+a[n/2-1])*1.0/2;
              //有奇数个元素
    else
        mid=a[n/2]*1.0;
    return mid;
}
int max(int a,int b
以下是使用分治法求解两个有序数组中位数的伪代码: ``` // 函数:findMedianSortedArrays // 参数:nums1 有序数组1,nums2 有序数组2 // 返回值:两个有序数组中位数 function findMedianSortedArrays(nums1, nums2) { // 确保 nums1 长度小于等于 nums2 长度 if (nums1.length > nums2.length) { return findMedianSortedArrays(nums2, nums1); } // 对 nums1 进行二分查,将两个数组分为两部分 let len1 = nums1.length; let len2 = nums2.length; let left = 0; let right = len1; while (left <= right) { let i = Math.floor((left + right) / 2); let j = Math.floor((len1 + len2 + 1) / 2) - i; // i 太小了,需要增加 if (i < len1 && nums2[j - 1] > nums1[i]) { left = i + 1; } // i 太大了,需要减少 else if (i > 0 && nums1[i - 1] > nums2[j]) { right = i - 1; } // i 符合条件 else { let maxLeft = 0; if (i === 0) { maxLeft = nums2[j - 1]; } else if (j === 0) { maxLeft = nums1[i - 1]; } else { maxLeft = Math.max(nums1[i - 1], nums2[j - 1]); } // 数组总长度为奇数,返回左半部分的最大值 if ((len1 + len2) % 2 === 1) { return maxLeft; } let minRight = 0; if (i === len1) { minRight = nums2[j]; } else if (j === len2) { minRight = nums1[i]; } else { minRight = Math.min(nums1[i], nums2[j]); } // 数组总长度为偶数,返回左半部分的最大值和右半部分的最小值的平均数 return (maxLeft + minRight) / 2; } } } ``` 该算法的时间复杂度为 O(log(min(m,n))),其 m 和 n 分别为两个数组的长度。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值