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;
}