寻找数组中的最大值和最小值(编程之美2.10,C++实现)
求N个元素的数组中最大(小)值,比较次数最少为N。那么同时求数组中的最大值和最小值,最少比较次数为多少呢?
最朴素的想法为2N次,一遍求最大,一遍求最小;
在此基础上,判定当前元素已经比最大值大时,无需同最小值比较,即可剩下一次比较;如下:
if(curElement > curMax){
curMax = curElement;
}else if(curElement < curMin){
curMin = curElement;
}
比较总次数的期望是:
,其中 (i-1)/i 为第二次比较执行的概率;
N足够大时的期望约为在2N - (lnN + C),其中C < 1;
这个时间复杂度显然是不够的!于是乎,在这里我们不妨考虑一下老少咸宜的分治法!(想到了这个点就容易出算法了!)
……
具体问题和解题思路《编程之美》P161已给出,毋庸赘述,这里我们直接上代码:
ArraysAndStrings.cpp
// ArraysAndStrings.cpp : 定义控制台应用程序的入口点。
// yunduxiaocheng 2013-5-25
#include "stdafx.h"
#include <iostream>
#include <cassert>
#include "Element.h"
using namespace std;
//find both max and min elements in the array arr[], divide and conquer
template <typename T>
bool findeMaxMin(const T arr[],unsigned int startIndex,unsigned int endIndex,T& outMax,T& outMin){
assert(arr);
assert(startIndex <= endIndex);
//leaf with only one element
if(startIndex == endIndex){
outMax = arr[startIndex];
outMin = arr[endIndex];
return true;
}
//leaf with two elements
if(startIndex + 1 == endIndex){
if(arr[startIndex] > arr[endIndex]){
outMax = arr[startIndex];
outMin = arr[endIndex];
}else{
outMax = arr[endIndex];
outMin = arr[startIndex];
}
return true;
}
//divide: recusively compute subproblems
unsigned int midIndex = startIndex + (endIndex - startIndex)/2;
T max1,max2,min1,min2;
if( !findeMaxMin(arr,startIndex,midIndex,max1,min1) || !findeMaxMin(arr,midIndex + 1,endIndex,max2,min2)){
return false;
}
//conquer: combine subresult
outMax = max1 > max2 ? max1 : max2;
outMin = min1 < min2 ? min1 : min2;
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
Element arr2[10];
Element max;
Element min;
for(int i = 0 ; i < 10;i ++){
arr2[i].setEleInt( i + 1);
}
if(findeMaxMin(arr2,0,9,max,min)){
cout << max.getEleInt() << ' ' << min.getEleInt() << endl;
}
return 0;
}
测试使用的元素类
Element.h
#pragma once
class Element
{
private:
int eleInt;
public:
Element(void);
Element(int a);
~Element(void);
int getEleInt() const;
void setEleInt(int a);
};
inline bool operator==(const Element& a,const Element& b){
if( a.getEleInt() == b.getEleInt()){
return true;
}
return false;
}
inline bool operator>(const Element& a,const Element& b){
if( a.getEleInt() > b.getEleInt()){
return true;
}
return false;
}
inline bool operator<(const Element& a,const Element& b){
if( a.getEleInt() < b.getEleInt()){
return true;
}
return false;
}
Element.cpp
#include "stdafx.h"
#include "Element.h"
Element::Element(void)
{
}
Element::Element(int a)
{
eleInt = a;
}
Element::~Element(void)
{
}
int Element::getEleInt() const{
return eleInt;
}
void Element::setEleInt(int a){
eleInt = a;
}