寻找数组中最大值和最小值
最简单的方法就是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(" "); int max; int min; int start; start = GetTime(); MaxMin(array, &max, &min); printf("time elapse:%d ", GetTime() - start); printf("max:%d min:%d ", max, min); start = GetTime(); MaxMin_1(array, &max, &min); printf("time elapse:%d ", GetTime() - start); printf("max:%d min:%d ", max, min); start = GetTime(); MaxMin_2(array, 0, array.size() - 1, &max, &min); printf("time elapse:%d ", GetTime() - start); printf("max:%d min:%d ", max, min); start = GetTime(); MaxMin_3(array, 0, array.size() - 1, &max, &min); printf("time elapse:%d ", GetTime() - start); printf("max:%d min:%d ", 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
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。