【编程之美】2.10 求数组中最大的数和最小的数
思路: 有学过
我想的是先把数组前后两两比较,把大的交换到前面,小的交换到后面。然后分别比较前后两个子数组,找最大和最小 需要比较 1.5N次
注意:奇数、偶数通过 i 和 j 区别处理了, 不用单独再写一个
#include <iostream> using namespace std; void getMaxAndMinNum(int * a, int alen, int *max, int *min) { int i, j; for(i = 0, j = alen - 1; i < j; i++, j--) //前面的元素都是比较后大的数 后面的元素都是比较后小的数 { if(a[i] < a[j]) { swap(a[i], a[j]); } } int k; *max = a[0]; *min = a[i]; for(k = 1; k <= j; k++) //对于奇数和偶数 i 和 j不同 所以可以用下面的统一处理 奇数时 i == j 偶数时 i > j { if(a[k] > *max) { *max = a[k]; } } for(k = i + 1; k < alen; k++) { if(a[k] < *min) { *min = a[k]; } } return; }
看答案,说上面的方法破坏了原数组,可以不破坏原数组。就是奇数位的和偶数位的比较,把较大的直接跟max比较,较小的跟min比较。去掉了交换的步骤。 注意只有一个元素时要单独判断。
void getMaxAndMinNumAns(int * a, int alen, int *max, int *min) { int i; if(alen == 1) //只有一个元素 { *max = a[0]; *min = a[0]; } else { int maxtmp, mintmp; *max = (a[0] >= a[1]) ? a[0] : a[1]; *min = (a[0] >= a[1]) ? a[1] : a[0]; for(i = 1; i < alen/2; i++) { maxtmp = (a[2 * i] >= a[2 * i + 1]) ? a[2 * i] : a[2 * i + 1]; mintmp = (a[2 * i] >= a[2 * i + 1]) ? a[2 * i + 1] : a[2 * i]; *max = (*max >= maxtmp) ? *max : maxtmp; *min = (*min <= mintmp) ? *min : mintmp; } if(alen & 0x01 == 1) //奇数个元素 对最后一个再做一次判断 { *max = (*max >= a[alen - 1]) ? *max : a[alen - 1]; *min = (*min <= a[alen - 1]) ? *min : a[alen - 1]; } } } int main() { int a[6] = {3,5,2,6,8,0}; int b[7] = {2,4,5,1,6,3,0}; int c[8] = {1,1,2,3,4,5,7,7}; int max = 0, min = 0; //getMaxAndMinNum(a, 6, &max, &min); //getMaxAndMinNum(b, 7, &max, &min); //getMaxAndMinNum(c, 8, &max, &min); getMaxAndMinNumAns(a, 6, &max, &min); getMaxAndMinNumAns(b, 7, &max, &min); getMaxAndMinNumAns(c, 8, &max, &min); return 0; }