分治法

本文深入探讨了排序算法(如归并排序、快速排序)和数据结构的应用,包括求第K小的数、数组中位数、最大值查找及二分搜索等核心算法。通过分治法和递归策略解决复杂问题,实现高效的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、归并排序

//将有二个有序数列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
	int i = first, j = mid + 1;
	int m = mid,   n = last;
	int k = 0;
	
	while (i <= m && j <= n)
	{
		if (a[i] < a[j])
			temp[k++] = a[i++];
		else
			temp[k++] = a[j++];
	}
	
	while (i <= m)
		temp[k++] = a[i++];
	
	while (j <= n)
		temp[k++] = a[j++];
	
	for (i = 0; i < k; i++)
		a[first + i] = temp[i];
}
void
 mergesort(int a[], int first, int last, int temp[])
{
	if (first < last)
	{
		int mid = (first + last) / 2;
		mergesort(a, first, mid, temp);    //左边有序
		mergesort(a, mid + 1, last, temp); //右边有序
		mergearray(a, first, mid, last, temp); //再将二个有序数列合并
	}
}

bool MergeSort(int a[], int n)
{
	int *p = new int[n];
	if (p == NULL)
		return false;
	mergesort(a, 0, n - 1, p);
	delete[] p;
	return true;
}

2、快速排序
//快速排序
void quick_sort(int s[], int l, int r)
{
    if (l < r)
    {
		//Swap(s[l], s[(l + r) / 2]); //将中间的这个数和第一个数交换 参见注1
        int i = l, j = r, x = s[l];
        while (i < j)
        {
            while(i < j && s[j] >= x) // 从右向左找第一个小于x的数
				j--;  
            if(i < j) 
				s[i++] = s[j];
			
            while(i < j && s[i] < x) // 从左向右找第一个大于等于x的数
				i++;  
            if(i < j) 
				s[j--] = s[i];
        }
        s[i] = x;
        quick_sort(s, l, i - 1); // 递归调用 
        quick_sort(s, i + 1, r);
    }
}

3.求第K小的数
基于快速排序的分治算法 
int FindSmall(int *a , int l , int r , int k){  
    if(l == r)    
        return a[l] ;  
    int i = l , j = r , x = a[(l+r)>>1] ;   
    while(i<=j) {  
        while(a[i] < x) ++ i ;   
        while(a[j] > x) -- j ;   
        if(i <= j){  
            swap( a[i], a[j] ) ;    
            ++i ;  --j ;   
        }  
    }  
    if(k <= j)    
        return FindSmall(a , l , j , k);  
    if(k >= i)    
        return FindSmall(a , i , r , k);  
}  
4、与查找第K小的数类似 一个数组的中位数也可用分治法求

5.求数组中最大值
int max(int a[], int l, int r) {
    int u, v;
    int m = l + (r - l)>>1;
    if (l == r) {
        return a[l];
    }
    u = max(a, l, m);
    v = max(a, m + 1, r);
    return (u > v ? u : v);
}
6、二分搜索
int binarySerach(int a[],int n,int x)
{
int left = 0,right = n - 1;
while(left <= right)
{
   int middle = left + (right - left)>>1;
   if(a[middle] == x) return middle;
   if(x > a[middle]) left = middle + 1;
   else right = middle - 1;
}
return -1;
}
}

7、数对只差最大


int MaxDiff_Solution1(int numbers[], unsigned length)
{
    if(numbers == NULL || length < 2)
        return 0;
 
    int max, min;
    return MaxDiffCore(numbers, numbers + length - 1, &max, &min);
}
 
int MaxDiffCore(int* start, int* end, int* max, int* min)
{
    if(end == start)
    {
        *max = *min = *start;
        return 0x80000000;
    }
 
    int* middle = start + (end - start) / 2;
 
    int maxLeft, minLeft;
    int leftDiff = MaxDiffCore(start, middle, &maxLeft, &minLeft);
 
    int maxRight, minRight;
    int rightDiff = MaxDiffCore(middle + 1, end, &maxRight, &minRight);
 
    int crossDiff = maxLeft - minRight;
 
    *max = (maxLeft > maxRight) ? maxLeft : maxRight;
    *min = (minLeft < minRight) ? minLeft : minRight;
 
    int maxDiff = (leftDiff > rightDiff) ? leftDiff : rightDiff;
    maxDiff = (maxDiff > crossDiff) ? maxDiff : crossDiff;
    return maxDiff;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值