两有序数组中位数 c语言实现

给定两个大小为 m 和 n 的有序数组 a 和 b。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设  a 和 b 不会同时为空。


#include<stdio.h>
#include<math.h>
#define min(a,b) a<b?a:b
double dg(int* a, int x1, int* b, int x2, int k, int length_a, int length_b);
double find(int* nums1, int nums1Size, int* nums2, int nums2Size){
	int k = 0, l;
	l = nums1Size + nums2Size;
	double m, n;
	l % 2 == 1 ? (k = l / 2 + 1) : (k = l / 2);
	if (nums1Size == 0){
		if (l % 2 == 1){
			m = nums2[k - 1];
		}
		else if (l % 2 == 0){
			m = nums2[k - 1];
			n = nums2[k];
			m = (m + n) / 2;
		}
		return m;
	}
	else if (nums2Size == 0){
		if (l % 2 == 1){
			m = nums1[k - 1];

		}
		else if (l % 2 == 0){
			m = nums1[k - 1];
			n = nums1[k];
			m = (m + n) / 2;
		}
		return m;
	}
	if (l % 2 == 1){
		return dg(nums1, 0, nums2, 0, k - 1,nums1Size,nums2Size);

	}
	double x = dg(nums1, 0, nums2, 0, k,nums1Size, nums2Size);
	printf("x %f\n", x);
	double y = dg(nums1, 0, nums2, 0, k + 1, nums1Size, nums2Size);
	printf(" y %f \n", y);
//	printf("xy %f \n", (x + y) / 2);
	return (x+y)/2;
}
double dg(int* a, int x1, int* b, int x2, int k,int length_a,int length_b){
	int i = 0;
	int g1 = 100, g2 = 100;//我这里定义100,是因为c语言里没有极大,
	if (x1 >= length_a) {   /*x1和x2用来排除较小数组的k/2的前半部分;以及作为递归结束的条件,当x的值大于数组长度时候说明已经遍历完那一数组,则第k个数在另一个数组。*/
		return b[x2 + k - 1];
	}
	if (x2 >= length_b) return a[x1 + k - 1];
	if (k == 1) {
		return min(a[x1], b[x2]);
	}
	int g1 = 100, g2 = 100;/*我这里定义100,是因为c语言里没有极大;这是为了避免k/2大数组长度的情况下发生错误;但是有更巧妙的方法,我就不写了。
	if (x1 + k / 2 - 1 < length_a){
		g1 = a[x1 + k / 2 - 1];
	}
	if (x2 + k / 2 - 1 < length_b){
		g2 = b[x2 + k / 2 - 1];
	}
	if (g1 < g2){
		return (dg(a, x1 + k / 2, b, x2, k - k / 2,length_a,length_b));//当a数组的g1<b的g2时,x1向后移动排除a数组之前g1的值
		
	}
	return (dg(a, x1, b, x2 + k / 2, k - k / 2, length_a,length_b));
}
void main(){
	int a[2] = { 1, 2 }, nums2[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	double aa = 0;
	aa = find(a, 2, nums2, 10);
	printf("%f", aa);
}

解题实现思路:
这一题可以当作是寻找第 k =(m + n)/ 2个数,常规方法是合并排序然后求中位数,但是有时间要求,不能使用合并排序。
解法一:根据中位数的特性,可以构造一个小堆,最右边的孩子就是中位数;
解法二:我使用的就是这个解法,由于这是两个有序数组,可以使用 a数组中的第 k/2个是和b数组的k/2个数比较大小。第k个数一定再较小那一数组的后半部分,或者较大数组的前半部分。然后进行递归,具体可以看代码注释;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值