求解最大值与最小值-分治算法

1 概述


无论是最好、最坏或者平均情况,该MaxMin分治算法所用的比较次数都是3n/2-2。
而实际中,任何一种以元素比较为基础的找最大值最小值元素的算法,其元素比较次数的下界为3n/2-2。
因此,从此种情况上分析,该算法是最优的。
但由于需要log(n)+1级的递归,而每次递归调用需要将 i j fmax fmin 和返回地址的值进行压栈,故需要额外占用一些内存空间。
当然,压出栈过程中也会带来时间开销。
特别是A中元素的比较次数和整数i j 的比较次数相近时,递归求最大最小算法未必比直接求解算法效率高。


2 伪代码


     //递归求最大最小值的分治算法
MaxMin(i,j,fmax,fmin) //A[1:n]是n元数组,
     //参数i,j :1≤i≤j≤n,使用该过程将数组
     // A[i..j]中的最大最小元分别赋给fmax和fmin。
      global n, A[1..n]; 
      integer i, j;
  if i=j then   
       fmax:=A[i]; fmin:=A[i]; 
	//子数组A[i..j]中只有一个元素
  else if i=j-1 then 
	//子数组A[i..j]中只有两个元素
      if A[i]<A[j] then
        fmin:=A[i]; fmax:=A[j];
      else fmin:=A[j]; fmax:=A[i];
      end{if}
  else   //子数组A[i..j]中的元素多于两个
        mid:=(i+j)/2; 
        MaxMin(i, mid, lmax, lmin);
        MaxMin(mid+1, j, rmax, rmin);
        fmax:=max(lmax, rmax);
        fmin:= minlmin, rmin);     
  end{if}
end{MaxMin} 

3 时间复杂度


时间复杂度


4 源码示例


// max_min.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#define n 10
int A[n];
int Max(int a, int b)
{
	return ((a >= b) ? a : b);
}
int Min(int a, int b)
{
	return ((a <= b) ? a : b);
}
void MaxMin(int i, int j, int &fmax, int &fmin)
{
	int mid;
	if (i == j)
	{
		fmax = A[i];
		fmin = A[i];
	}
	else if(i==j-1)
	{
		if (A[i] < A[j])
		{
			fmin = A[i];
			fmax = A[j];
		}
		else
		{
			fmin = A[j];
			fmax = A[i];
		}
	}
	else
	{
		int lmax, lmin, rmax, rmin;
		mid = floor((i + j) / 2);
		MaxMin(i, mid, lmax, lmin);
		MaxMin(mid + 1, j, rmax, rmin);
		fmax = Max(lmax, rmax);
		fmin = Min(lmin, rmin);
	}
}
int main()
{
	for (int i = 0; i < n; i++)
	{
		scanf_s("%d", &A[i]);
	}	
	int fmax, fmin;
	MaxMin(0, n-1, fmax, fmin);
	printf("\n\n最大值为:%d\n最小值为:%d\n\n", fmax, fmin);

    return 0;
}



评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值