寻找数组中最大值和最小值

时间:2023-01-12 15:14:09

最简单的方法就是N中的每个数分别和max,min比较,看似2N次比较,其实大于max的就不必和min比较,小于min的也不必和max比较,因此比较的次数不足2N次,程序如下:

bool MaxMin(std::vector<T> array, T* max, T* min) {
if (array.size() < 1) {
return false;
}
*max = array[0];
*min = array[0];
size_t array_size = array.size();
for (int i = 1; i < array_size; ++i) {
if (array[i] > *max) {
*max = array[i];
} else if (array[i] < *min) {
*min = array[i];
}
}
return true;
}

其次方法是数组中的一对一对的数相互比较,比较中较大的一个和max比较,较小的和min比较,总计有N/2对数,分别和max和min进行一次比较,共计3N/2次比较,程序代码如下:

template<typename T>
bool MaxMin_1(std::vector<T> array, T* max, T* min) {
if (array.size() < 1) {
return false;
}
*max = array[0];
*min = array[0];
int index = 1;
int array_size = array.size();
while(index < array_size && index +1 <array_size) {
if (array[index] >= array[index + 1]) {
if (array[index] > *max) {
*max = array[index];
}
if (array[index + 1] < *min) {
*min = array[index + 1];
}
} else {
if (array[index + 1] > *max) {
*max = array[index + 1];
}
if (array[index] < *min) {
*min = array[index];
}
}
index += 2;
}
if (index < array.size()) {
if (array[index] > *max) {
*max = array[index];
}
if (array[index] < *min) {
*min = array[index];
}
}
return true;
}

最后一种方法是分治法,比较次数也是3N/2,程序如下:

template<typename T>
bool MaxMin_2(std::vector<T> array, int start, int end, T* max, T* min) {
if (end - start > 1) {
MaxMin_2(array, start, (start + end) / 2, max, min);
MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
} else {
if (array[end] > array[start]) {
if (array[end] > *max) {
*max = array[end];
}
if (array[start] < *min) {
*min = array[start];
}
} else {
if (array[start] > *max) {
*max = array[start];
}
if (array[end] < *min) {
*min = array[end];
}
}
}
}
template<typename T>
bool MaxMin_3(std::vector<T> array, int start, int end, T* max, T* min) {
if (end > start) {
MaxMin_2(array, start, (start + end) / 2, max, min);
MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
} else {
if (array[start] > *max) {
*max = array[start];
}
if (array[start] < *min) {
*min = array[start];
}
}
}

为了测试性能,完成比较程序如下:

#include <stdio.h>
#include <vector>
#include <stdlib.h>
#include <sys/time.h>
template<typename T>
bool MaxMin(std::vector<T> array, T* max, T* min) {
if (array.size() < 1) {
return false;
}
*max = array[0];
*min = array[0];
size_t array_size = array.size();
for (int i = 1; i < array_size; ++i) {
if (array[i] > *max) {
*max = array[i];
} else if (array[i] < *min) {
*min = array[i];
}
}
return true;
}
template<typename T>
bool MaxMin_1(std::vector<T> array, T* max, T* min) {
if (array.size() < 1) {
return false;
}
*max = array[0];
*min = array[0];
int index = 1;
int array_size = array.size();
while(index < array_size && index +1 <array_size) {
if (array[index] >= array[index + 1]) {
if (array[index] > *max) {
*max = array[index];
}
if (array[index + 1] < *min) {
*min = array[index + 1];
}
} else {
if (array[index + 1] > *max) {
*max = array[index + 1];
}
if (array[index] < *min) {
*min = array[index];
}
}
index += 2;
}
if (index < array.size()) {
if (array[index] > *max) {
*max = array[index];
}
if (array[index] < *min) {
*min = array[index];
}
}
return true;
}
template<typename T>
bool MaxMin_2(std::vector<T> array, int start, int end, T* max, T* min) {
if (end - start > 1) {
MaxMin_2(array, start, (start + end) / 2, max, min);
MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
} else {
if (array[end] > array[start]) {
if (array[end] > *max) {
*max = array[end];
}
if (array[start] < *min) {
*min = array[start];
}
} else {
if (array[start] > *max) {
*max = array[start];
}
if (array[end] < *min) {
*min = array[end];
}
}
}
}
template<typename T>
bool MaxMin_3(std::vector<T> array, int start, int end, T* max, T* min) {
if (end > start) {
MaxMin_2(array, start, (start + end) / 2, max, min);
MaxMin_2(array, (start + end) / 2 + 1, end, max, min);
} else {
if (array[start] > *max) {
*max = array[start];
}
if (array[start] < *min) {
*min = array[start];
}
}
}

int GetTime() {
timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000 + tv.tv_usec;
}
int main(int argc, char** argv) {
const int kArraySize = 10000;
std::vector<int> array;
for (int i = 0; i < kArraySize; ++i) {
array.push_back(rand());
// printf("%d ", array[i]);
}
printf("\n");
int max;
int min;
int start;
start = GetTime();
MaxMin(array, &max, &min);
printf("time elapse:%d\n", GetTime() - start);
printf("max:%d min:%d\n", max, min);

start = GetTime();
MaxMin_1(array, &max, &min);
printf("time elapse:%d\n", GetTime() - start);
printf("max:%d min:%d\n", max, min);
start = GetTime();
MaxMin_2(array, 0, array.size() - 1, &max, &min);
printf("time elapse:%d\n", GetTime() - start);
printf("max:%d min:%d\n", max, min);
start = GetTime();
MaxMin_3(array, 0, array.size() - 1, &max, &min);
printf("time elapse:%d\n", GetTime() - start);
printf("max:%d min:%d\n", max, min);
}

执行结果:

./a.out 

time elapse:187
max:2147469841 min:100669
time elapse:216
max:2147469841 min:100669
time elapse:86513
max:2147469841 min:100669
time elapse:82481
max:2147469841 min:100669

结论:最简单的方法效率最高,分治法由于迭代效率非常差,这是我想到了分治法的归并排序,估计性能也不会好,改天比较一下。


参考文献:

编程之美 2.10