编程之美4:求数组中的最大值和最小值
方法1:暴力方法 遍历一遍数组,比较2*N次求出最大值和最小值
方法2:改进方法 (破坏了原数组)
遍历一遍数组使得下标为偶数的元素较下标为奇数的元素大,再分别求出最大值和最小值
比较次数为3*N/2次
方法3:改进方法 (不破坏原数组)
遍历一遍数组将相邻元素中较大值和nMax比较,将较小值和nMin比较
比较次数为3*N/2次
方法4:改进方法
分治思想,先分别求出前半部分和后半部分数组的最大值和最小值,
然后两部分中的最大值和最小值分别比较求出整个数组的最大值和最小值
比较次数为3*N/2-2次
代码如下:
// 求数组中的最大值最小值.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <iostream> using namespace std; //方法一:暴力方法 遍历一遍数组,比较2*N次求出最大值和最小值 void FindMaxAndMinMethod1(int *pArr, int nLength, int &nMax, int &nMin) { if (pArr == NULL || nLength <= 0) { cout << "输入有误!" << endl; return; } nMax = pArr[0]; nMin = pArr[0]; for (int i=1; i<nLength; i++) { if (nMin > pArr[i]) { nMin = pArr[i]; } if (nMax < pArr[i]) { nMax = pArr[i]; } } } //方法二:改进方法 (破坏了原数组) //遍历一遍数组使得下标为偶数的元素较下标为奇数的元素大,再分别求出最大值和最小值 //比较次数为3*N/2次 void FindMaxAndMinMethod2(int *pArr, int nLength, int &nMax, int &nMin) { if (pArr != NULL && nLength > 0) { if (nLength == 1)//数组只有一个元素 { nMax = pArr[0]; nMin = pArr[0]; return; } if (nLength == 2)//数组只有两个元素 { if (pArr[0] > pArr[1]) { nMax = pArr[0]; nMin = pArr[1]; } else { nMax = pArr[1]; nMin = pArr[0]; } return; } //遍历一遍数组使得下标为偶数的元素较下标为奇数的元素大 for (int i=0; i<nLength; i+=2) { if (i+1 < nLength && pArr[i] < pArr[i+1]) { int nTemp = pArr[i]; pArr[i] = pArr[i+1]; pArr[i+1] = nTemp; } } //求最大值 nMax = pArr[0]; for (int j=2; j<nLength; j+=2) { if (nMax < pArr[j]) { nMax = pArr[j]; } } //求最小值 nMin = pArr[1]; for (int t=3; t<nLength; t+=2) { if (nMin > pArr[t]) { nMin = pArr[t]; } } } } //方法三:改进方法 (不破坏原数组) //遍历一遍数组将相邻元素中较大值和nMax比较,将较小值和nMin比较 //比较次数为3*N/2次 void FindMaxAndMinMethod3(int *pArr, int nLength, int &nMax, int &nMin) { if (pArr != NULL && nLength > 0) { if (nLength == 1)//数组只有一个元素 { nMax = pArr[0]; nMin = pArr[0]; return; } if (nLength == 2)//数组只有两个元素 { if (pArr[0] > pArr[1]) { nMax = pArr[0]; nMin = pArr[1]; } else { nMax = pArr[1]; nMin = pArr[0]; } return; } //初始赋值 if (pArr[0] > pArr[1]) { nMax = pArr[0]; nMin = pArr[1]; } else { nMax = pArr[1]; nMin = pArr[0]; } for (int i=2; i<nLength; i+=2) { if (i+1 < nLength && pArr[i] < pArr[i+1]) { if (nMax < pArr[i+1])//将较大值和nMax比较 { nMax = pArr[i+1]; } if (nMin > pArr[i])//将较小值和nMin比较 { nMin = pArr[i]; } } else if (i+1 < nLength && pArr[i] > pArr[i+1]) { if (nMax < pArr[i])//将较大值和nMax比较 { nMax = pArr[i]; } if (nMin > pArr[i+1])//将较小值和nMin比较 { nMin = pArr[i+1]; } } else//最后剩下一个元素 { if (nMax < pArr[i]) { nMax = pArr[i]; } if (nMin > pArr[i]) { nMin = pArr[i]; } } } } } //方法四:改进方法 //分治思想,先分别求出前半部分和后半部分数组的最大值和最小值, //然后两部分中的最大值和最小值分别比较求出整个数组的最大值和最小值 //比较次数为3*N/2-2次 void FindMaxAndMinMethod4(int *pArr, int nStart, int nEnd, int &nMax, int &nMin) { if (nEnd - nStart <= 1) { if (pArr[nStart] > pArr[nEnd]) { nMax = pArr[nStart]; nMin = pArr[nEnd]; } else { nMax = pArr[nEnd]; nMin = pArr[nStart]; } return; } int nLeftMax = 0; int nLeftMin = 0; int nRightMax = 0; int nRightMin = 0; FindMaxAndMinMethod4(pArr, nStart, nStart+(nEnd-nStart)/2, nLeftMax, nLeftMin); FindMaxAndMinMethod4(pArr, nStart+(nEnd-nStart)/2+1, nEnd, nRightMax, nRightMin); nMax = nLeftMax > nRightMax ? nLeftMax : nRightMax; nMin = nLeftMin < nRightMin ? nLeftMin : nRightMin; } int _tmain(int argc, _TCHAR* argv[]) { //int nArr[1] = {-4}; //int nArr[2] = {-4,-1}; //int nArr[3] = {-4,-1,0}; int nArr[5] = {-4,-1,0, 8,9}; int max = 0; int min = 0; FindMaxAndMinMethod1(nArr, 5, max, min); cout << "最大值为:" << max << " 最小值为:" << min << endl; max = 0; min = 0; FindMaxAndMinMethod2(nArr, 5, max, min); cout << "最大值为:" << max << " 最小值为:" << min << endl; max = 0; min = 0; FindMaxAndMinMethod3(nArr, 5, max, min); cout << "最大值为:" << max << " 最小值为:" << min << endl; max = 0; min = 0; FindMaxAndMinMethod4(nArr, 0, 4, max, min); cout << "最大值为:" << max << " 最小值为:" << min << endl; system("pause"); return 0; }
运行结果: