遞歸的定義
遞歸,就是在運行的過程中調用自己。
遞歸必須要有三個要素:
①、邊界條件
②、遞歸前進段
③、遞歸返回段
當邊界條件不滿足時,遞歸前進;當邊界條件滿足時,遞歸返回。
實例:
利用遞歸求一個數的階乘
n! = n*(n-1)*(n-2)*......1
規定:
①、0!=1
②、1!=1
③、負數沒有階乘
//利用遞歸進行求一個數的乘層
public static int getFactorialFor(int n){
if((1 == n)||(0 == n)){
return 1;
}else{
return n*getFactorialFor(n-1);
}
}
遞歸的二分查找
注意:二分查找的數組一定是有序的!!!
在有序數組array[]中,不斷將數組的中間值(mid)和被查找的值比較,如果被查找的值等於array[mid],就返回下標mid; 否則,就將查找範圍縮小一半。如果被查找的值小於array[mid], 就繼續在左半邊查找;如果被查找的值大於array[mid], 就繼續在右半邊查找。 直到查找到該值或者查找範圍爲空時, 查找結束。
//利用遞歸進行二分查找
public static int findTwoPoint(int[] array,int key,int low,int height){
int mid = (low + height) / 2;
if(((0 == mid) || ((array.length - 1) == mid))&&(array[mid] != key)){
return -1;
}
if(array[mid] == key){
return mid;
}else if(array[mid] > key){
return findTwoPoint(array,key,low,mid-1);
}else if(array[mid] < key){
return findTwoPoint(array,key,mid+1,height);
}
return -1;
}
歸併排序
歸併算法的中心是歸併兩個已經有序的數組。歸併兩個有序數組A和B,就生成了第三個有序數組C。數組C包含數組A和B的所有數據項。
歸併排序的思想是把一個數組分成兩半,排序每一半,然後用上面的sort()方法將數組的兩半歸併成爲一個有序的數組。如何來爲每一部分排序呢?這裏我們利用遞歸的思想:
把每一半都分爲四分之一,對每個四分之一進行排序,然後把它們歸併成一個有序的一半。類似的,如何給每個四分之一數組排序呢?把每個四分之一分成八分之一,對每個八分之一進行排序,以此類推,反覆的分割數組,直到得到的子數組是一個數據項,那這就是這個遞歸算法的邊界值,也就是假定一個數據項的元素是有序的。
public static int[] mergeSort(int[] c,int start,int last){
if(last > start){
//也可以是(start+last)/2,這樣寫是爲了防止數組長度很大造成兩者相加超過int範圍,導致溢出
int mid = start + (last - start)/2;
mergeSort(c,start,mid);//左邊數組排序
mergeSort(c,mid+1,last);//右邊數組排序
merge(c,start,mid,last);//合併左右數組
}
return c;
}
public static void merge(int[] c,int start,int mid,int last){
int[] temp = new int[last-start+1];//定義臨時數組
int i = start;//定義左邊數組的下標
int j = mid + 1;//定義右邊數組的下標
int k = 0;
while(i <= mid && j <= last){
if(c[i] < c[j]){
temp[k++] = c[i++];
}else{
temp[k++] = c[j++];
}
}
//把左邊剩餘數組元素移入新數組中
while(i <= mid){
temp[k++] = c[i++];
}
//把右邊剩餘數組元素移入到新數組中
while(j <= last){
temp[k++] = c[j++];
}
//把新數組中的數覆蓋到c數組中
for(int k2 = 0 ; k2 < temp.length ; k2++){
c[k2+start] = temp[k2];
}
}