输入n个数,求出该序列的最大和最小值。
参考:
http://blog.csdn.net/kennyrose/article/details/7376457
http://www.360doc.com/content/12/0903/10/1317564_233893635.shtml
http://www.cnblogs.com/goodwin/archive/2010/11/01/1866391.html
http://blog.csdn.net/yyywyr/article/details/8003366
分治算法通俗的讲就是把一个规模比较大的问题分成n个规模较小的问题来解决,再将每个小规模的问题进行合并,最后得到结果。通常问题规模比较大难以用普通的编程方法实现,或者不可能实现的时候采用分治算法,能够简化问题的解决。
一个例子:
求出一个数组中的最大值和最小值。
写的比较好的代码:
1 #include<iostream> 2 3 void dcMaxMin( int [], int, int, int *, int * ); 4 5 void dcMaxMin( int arr[], int low, int high, int *tmpMax, int *tmpMin ) 6 { 7 if ( high - low <= 1)// 最多俩元素 8 { 9 if (arr[low] <= arr[high] ) 10 { 11 *tmpMax = arr[high]; 12 *tmpMin = arr[low]; 13 return; // 递归出口 14 } 15 else 16 { 17 *tmpMax = arr[low]; 18 *tmpMin = arr[high]; 19 return; //递归出口 20 } 21 } 22 23 int min1, min2, max1, max2; 24 int mid = ( high - low ) / 2 + low; 25 //递归开始 26 dcMaxMin(arr, low, mid, &max1, &min1); 27 dcMaxMin(arr, mid+1, high, &max2, &min2); 28 29 *tmpMax = max1 < max2 ? max2 : max1; 30 *tmpMin = min1 < min2 ? min1 : min2; 31 32 } 33 34 int main() 35 { 36 int arr[] = {4, 1, 2, 9, 8, 3}; 37 int len = sizeof ( arr ) / sizeof( int ); 38 int max, min; 39 max = arr[0]; 40 min = arr[0]; 41 dcMaxMin(arr, 0, len-1, &max, &min); 42 std::cout << max << " " << min << std::endl; 43 44 return 0; 45 }
1 #include <iostream> 2 using namespace std; 3 void min_max(int a[],int i,int j,int &min,int &max) 4 { 5 int mid,max1,max2,min1,min2; 6 if(i==j){ 7 max=a[i]; 8 min=a[i]; 9 return ; 10 } 11 if(j==i+1) 12 { 13 if(a[i]>a[j]){min=a[j];max=a[i];} 14 else{min=a[i];max=a[j];} 15 } 16 else 17 { 18 mid=(i+j)/2; 19 min_max(a,i,mid,min1,max1); 20 min_max(a,mid+1,j,min2,max2); 21 if(min1>min2)min=min2; 22 else min=min1; 23 if(max1>max2)max=max1; 24 else max=max2; 25 } 26 } 27 int main() 28 { 29 int n,m,a[100],min,max; 30 cin>>n; 31 while(n!=0) 32 { 33 cin>>m; 34 for(int i=1;i<=m;i++)cin>>a[i]; 35 min_max(a,1,m,min,max); 36 cout<<min<<' '<<max<<endl; 37 n--; 38 } 39 return 0; 40 }
1 package example; 2 3 public class MaxAndMinValue { 4 5 // 直接算法 得到最大值和最小值 6 public static void main(String[] args) { 7 int[] A = { -18, -16, 9, -5, 7, -40, 0, 35 }; 8 System.out.println(getMaxValue(A)); 9 System.out.println(getMinValue(A)); 10 System.out.println(getMax(A, 0, A.length - 1)); 11 12 } 13 14 // 直接算法求最大值 15 public static int getMaxValue(int[] array) { 16 int Max = 0; 17 for (int i = 0; i < (array.length - 1); i++) { 18 if (array[i] == array[i + 1]) { 19 Max = array[i + 1]; 20 } 21 if (array[i] < array[i + 1]) { 22 Max = array[i + 1]; 23 } 24 if (array[i] > array[i + 1]) { 25 Max = array[i]; 26 array[i] = array[i + 1]; 27 array[i + 1] = Max; 28 29 } 30 } 31 return Max; 32 } 33 34 // 直接算法求最小值 35 public static int getMinValue(int[] array) { 36 37 int Min = 0; 38 for (int i = 0; i < (array.length - 1); i++) { 39 if (array[i] == array[i + 1]) { 40 Min = array[i + 1]; 41 } else if (array[i] < array[i + 1]) { 42 Min = array[i]; 43 array[i] = array[i + 1]; 44 array[i + 1] = Min; 45 } else if (array[i] > array[i + 1]) { 46 Min = array[i + 1]; 47 } 48 } 49 return Min; 50 } 51 52 // 用分治法求最大最小值 53 public static int getMax(int[] array, int i, int j) { 54 int Max1 = 0; 55 int Max2 = 0; 56 if (i == j) { 57 return Max1 = Max2 = array[j]; 58 } else if (i == (j - 1)) { 59 Max1 = array[i]; 60 Max2 = array[j]; 61 return Max1 > Max2 ? Max1 : Max2; 62 } else { 63 int mid = (i + j) / 2; 64 Max1 = getMax(array, i, mid); 65 Max2 = getMax(array, mid, j); 66 return Max1 > Max2 ? Max1 : Max2; 67 } 68 } 69 } 70 71 72 假设数组的大小为8,用直接的算法,最大值最小值总需要比较14次,而用分治算法可以一次性求出最大和最小,只需要10次比较。
1 ** 2 * 3 * 分治法求数组的最小值和最大值 4 */ 5 import java.util.Arrays; 6 7 public class MinAndMaxArray { 8 public static void main(String[] args) { 9 int arr[] = { -2, -9, 0, 5, 2 }; 10 int result[] = new int[2]; 11 result = minMax(arr, 0, arr.length - 1); 12 System.out.println(Arrays.toString(result)); 13 } 14 15 public static int[] minMax(int[] arr, int l, int r) { 16 int min = 0; 17 int max = 0; 18 if (l == r) { 19 min = arr[l]; 20 max = arr[l]; 21 } else if (l + 1 == r) { 22 if (arr[l] < arr[r]) { 23 min = arr[l]; 24 max = arr[r]; 25 } else { 26 min = arr[r]; 27 max = arr[l]; 28 } 29 } else { 30 int mid = (l + r) / 2; 31 int[] preHalf = minMax(arr, l, mid); 32 int[] postHalf = minMax(arr, mid + 1, r); 33 min = preHalf[0] < postHalf[0] ? preHalf[0] : postHalf[0]; 34 max = preHalf[1] > postHalf[1] ? preHalf[1] : postHalf[1]; 35 } 36 37 return new int[] { min, max }; 38 } 39 }
我自己写的代码:(保留以作备份)——以后尽量使用引用,而不要使用指针来传递参数。
1 #include<stdio.h> 2 #include<time.h> 3 #include<stdlib.h> 4 int maxMin(int *a,int i,int j,int *max,int *min); 5 int main() 6 { 7 int *a; 8 int i,n; 9 int max,min; 10 11 scanf("%d",&n); 12 a=(int *)malloc(sizeof(int)*n); 13 srand((unsigned int)time(0)); 14 for(i=0;i<n;i++) a[i]=rand()%91+10; 15 for(i=0;i<n;i++) 16 { 17 printf("%d ",a[i]); 18 if((i+1)%5==0) printf(" "); 19 } 20 printf(" "); 21 maxMin(a,0,n-1,&max,&min); 22 printf("%d %d ",max,min);/**/ 23 return 0; 24 } 25 int maxMin(int *a,int i,int j,int *max,int *min) 26 { 27 int mid; 28 int lmax,lmin,rmax,rmin; 29 if(j==i) { *max=a[i]; *min=a[i]; return 0;} 30 else if(j-i==1) 31 { 32 if(a[i]>a[j]) {*max=a[i];*min=a[j];return 0;} 33 else {*max=a[j];*min=a[i];return 0;} 34 } 35 else 36 { 37 mid=i+(j-i)/2; 38 maxMin(a,i,mid,&lmax,&lmin); 39 maxMin(a,mid+1,j,&rmax,&rmin); 40 if(lmax>rmax) *max=lmax; 41 else *max=rmax; 42 if(lmin<rmin) *min=lmin; 43 else *min=rmin; 44 } 45 return 0; 46 }