數列最值的遞迴解法
阿新 • • 發佈:2018-12-31
在看到輾轉相除法的遞迴解法後,不禁想到涉及比較的分治演算法、三目運算子和遞迴簡直就是絕配,一眨眼,腦海中就迸出了數列最小值的遞迴解法,每一個數都與後面陣列的最小值相比較,思路有了,動手吧。
- //輾轉相除法
- int gcd_division(int a,int b)
- {
- return b==0?a:gcd_division(b,a%b);
- }
一、思路與改進
將陣列每一個元素與該元素後陣列最小值相比較,最後一個數組元素返回自身,即可得到整個陣列的最小值。圖示如下:
轉化成程式碼就是這樣一個函式:
-
//arr[]:陣列 len:陣列長度 n:
- int f(int arr[],int len,int n)
- {
- if(n == len-1)
- return arr[n];
- return arr[n]<f(arr,len,n+1)?arr[n]:f(arr,len,n+1);
-
}
跑一遍:
沒問題,不過這遞迴把f(arr,len,n+1)算了兩遍,效率太低了,得改。先求結果,再把結果放入return裡。程式碼如下:
- //arr[]:陣列 len:陣列長度 n:當前下標
-
int f(int arr[],int len,int n)
- {
- if(n == len-1)
- return arr[n];
- int min = f(arr,len,n+1);
- return arr[n]<min?arr[n]:min;
-
}
ok,效率提升了,不過這樣的話,三目運算子就只剩下一個比較的操作了,可以再精簡一下,定義一個比較元素的巨集:MIN(X,Y)
- #define MIN(X,Y) ((X<Y)?(X):(Y))
改一下return裡的語句:
- //arr[]:陣列 len:陣列長度 n:當前下標
-
int f(int
- {
- if(n == len-1)
- return arr[n];
- int min = f(arr,len,n+1);
- return MIN(min,arr[n]);
-
}
搞定~
原始碼:
- #include <stdio.h>
- #define N 10
- #define MIN(X,Y) ((X<Y)?(X):(Y))
- int f(int arr[],int len,int n)
- {
- if(n == len-1)
- return arr[n];
- int min = f(arr,len,n+1);
- return MIN(min,arr[n]);
- }
- int main (void)
- {
- int arr[N] = {2,4,1,3,5,6,7,8,-11};
- int min = f(arr,N,0);
- printf("%d ",min);
- return 0;
- }