+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
遞歸 是一種方法(函數)調用自己的編程技術
++++++++++++++++++++++++++++++++++++++++++++++++
三角數字 1,3,6,10,15.....數列中第n項是由 第n-1項的值加上n得到的。
遞歸:
int triangle(int n){
if(n==1)
return 1; //遞歸的出口
else
return ( n+triangle(n-1) )
}
++++++++++++++++++++++++++++++++++++++++++++++++++
階乘
1 1*1 1
2 2*1 2
3 3*2*1 6
4 4*3*2*1 24
遞歸
int factorial(int n){
if(n ==1){
return 1;
}else{
return ( n*factorial(n-1) )
}
}
++++++++++++++++++++++++++++++++++++++++++++++++++
變位字 !!!!《*****》
++++++++++++++++++++++++++++++++++++++++++++++++++
遞歸的二分查找
遞歸的二分查找《while循環 變成了 遞歸調用》
++++++++++++++++++++++++++++++++++++++++++++++++++
漢諾塔問題
++++++++++++++++++++++++++++++++++++++++++++++++++
歸併排序:
歸併排序比簡單排序《冒泡、選擇、插入》高效,冒泡、選擇、插入都要用O(N^2)時間。而歸併排序只要O(N*logN)
若N爲10000的話, N^2爲100000000(億) N*logN爲40000。換成時間的比例,歸併耗時40秒。則插入耗時28個小時。
缺點:需要在存儲器中 有另一個 大小等於被排序數據項數據的數組。如果有足夠的存儲空間,歸併是個不錯選擇。
歸併兩個有序數組
歸併算法的中心是歸併兩個已經有序的數組。歸併兩個有序數組AB,就生成第三個數組C。數組C包含AB的所有項。
核心代碼: 注意三個while循環的寫法!!!
public static void merge( int[] arrayA, int sizeA,
int[] arrayB, int sizeB,
int[] arrayC )
{
int aDex=0, bDex=0, cDex=0;
while(aDex < sizeA && bDex < sizeB) // neither array empty
if( arrayA[aDex] < arrayB[bDex] )
arrayC[cDex++] = arrayA[aDex++];
else
arrayC[cDex++] = arrayB[bDex++];
while(aDex < sizeA) // arrayB is empty,
arrayC[cDex++] = arrayA[aDex++]; // but arrayA isn't
while(bDex < sizeB) // arrayA is empty,
arrayC[cDex++] = arrayB[bDex++]; // but arrayB isn't
} // end merge()
真正的歸併排序:
核心思想:把一個數組分成兩半,排序每一半。然後用merge()方法把數組的兩半歸併成一個有序數組。
如何爲每一部分排序呢? 遞歸。
核心代碼:
public void mergeSort() // called by main()
{ // provides workspace
long[] workSpace = new long[nElems];
recMergeSort(workSpace, 0, nElems-1); //第一次調用 開始的腳標0 最大的 nElems-1
}
//-----------------------------------------------------------
private void recMergeSort(long[] workSpace, int lowerBound, int upperBound)
{
if(lowerBound == upperBound) // if range is 1,
return; // no use sorting
else
{ // find midpoint
int mid = (lowerBound+upperBound)/2;
recMergeSort(workSpace, lowerBound, mid); // sort low half
recMergeSort(workSpace, mid+1, upperBound);// sort high half
merge(workSpace, lowerBound, mid+1, upperBound);// merge them
} // end else
} // end recMergeSort()
//-----------------------------------------------------------
private void merge(long[] workSpace, int lowPtr, int highPtr, int upperBound)
{
int j = 0; // workspace index
int lowerBound = lowPtr;
int mid = highPtr-1;
int n = upperBound-lowerBound+1; // # of items
while(lowPtr <= mid && highPtr <= upperBound)
if( theArray[lowPtr] < theArray[highPtr] )
workSpace[j++] = theArray[lowPtr++];
else
workSpace[j++] = theArray[highPtr++];
while(lowPtr <= mid)
workSpace[j++] = theArray[lowPtr++];
while(highPtr <= upperBound)
workSpace[j++] = theArray[highPtr++];
for(j=0; j<n; j++)
theArray[lowerBound+j] = workSpace[j];
} // end merge()
++++++++++++++++++++++++++++++++++++++++++++++++++
消除遞歸:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《1》三角數字 遞歸
// triangle.java
// evaluates triangular numbers
// to run this program: C>java TriangleApp
import java.io.*;
////////////////////////////////////////////////////////////////
class TriangleApp
{
static int theNumber;
public static void main(String[] args) throws IOException
{
System.out.print("Enter a number: ");
theNumber = getInt();
int theAnswer = triangle(theNumber);
System.out.println("Triangle="+theAnswer);
} // end main()
//-------------------------------------------------------------
public static int triangle(int n)
{
if(n==1)
return 1;
else
return ( n + triangle(n-1) );
}
//-------------------------------------------------------------
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-------------------------------------------------------------
public static int getInt() throws IOException
{
String s = getString();
return Integer.parseInt(s);
}
//--------------------------------------------------------------
} // end class TriangleApp
////////////////////////////////////////////////////////////////
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《2》變位字 遞歸
// anagram.java
// creates anagrams
// to run this program: C>java AnagramApp
import java.io.*;
////////////////////////////////////////////////////////////////
class AnagramApp
{
static int size;
static int count;
static char[] arrChar = new char[100];
//-----------------------------------------------------------
public static void main(String[] args) throws IOException
{
System.out.print("Enter a word: "); // get word
String input = getString();
size = input.length(); // find its size
count = 0;
for(int j=0; j<size; j++) // put it in array
arrChar[j] = input.charAt(j);
doAnagram(size); // anagram it
} // end main()
//-----------------------------------------------------------
public static void doAnagram(int newSize)
{
int limit;
if(newSize == 1) // if too small,
return; // go no further
for(int j=0; j<newSize; j++) // for each position,
{
doAnagram(newSize-1); // anagram remaining
if(newSize==2) // if innermost,
displayWord(); // display it
rotate(newSize); // rotate word
}
}
//-----------------------------------------------------------
// rotate left all chars from position to end
public static void rotate(int newSize)
{
int j;
int position = size - newSize;
char temp = arrChar[position]; // save first letter
for(j=position+1; j<size; j++) // shift others left
arrChar[j-1] = arrChar[j];
arrChar[j-1] = temp; // put first on right
}
//-----------------------------------------------------------
public static void displayWord()
{
if(count < 99)
System.out.print(" ");
if(count < 9)
System.out.print(" ");
System.out.print(++count + " ");
for(int j=0; j<size; j++)
System.out.print( arrChar[j] );
System.out.print(" ");
System.out.flush();
if(count%6 == 0)
System.out.println("");
}
//-----------------------------------------------------------
public static String getString() throws IOException
{
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
//-----------------------------------------------------------
} // end class AnagramApp
////////////////////////////////////////////////////////////////
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《3》遞歸的二分查找《while循環 變成了 遞歸調用》
// binarySearch.java
// demonstrates recursive binary search
// to run this program: C>java BinarySearchApp
////////////////////////////////////////////////////////////////
class ordArray
{
private long[] a; // ref to array a
private int nElems; // number of data items
//-----------------------------------------------------------
public ordArray(int max) // constructor
{
a = new long[max]; // create array
nElems = 0;
}
//-----------------------------------------------------------
public int size()
{ return nElems; }
//-----------------------------------------------------------
public int find(long searchKey)
{
return recFind(searchKey, 0, nElems-1);
}
//-----------------------------------------------------------
private int recFind(long searchKey, int lowerBound,
int upperBound)
{
int curIn;
curIn = (lowerBound + upperBound ) / 2;
if(a[curIn]==searchKey)
return curIn; // found it
else if(lowerBound > upperBound)
return nElems; // can't find it
else // divide range
{
if(a[curIn] < searchKey) // it's in upper half
return recFind(searchKey, curIn+1, upperBound);
else // it's in lower half
return recFind(searchKey, lowerBound, curIn-1);
} // end else divide range
} // end recFind()
//-----------------------------------------------------------
public void insert(long value) // put element into array
{
int j;
for(j=0; j<nElems; j++) // find where it goes
if(a[j] > value) // (linear search)
break;
for(int k=nElems; k>j; k--) // move bigger ones up
a[k] = a[k-1];
a[j] = value; // insert it
nElems++; // increment size
} // end insert()
//-----------------------------------------------------------
public void display() // displays array contents
{
for(int j=0; j<nElems; j++) // for each element,
System.out.print(a[j] + " "); // display it
System.out.println("");
}
//-----------------------------------------------------------
} // end class ordArray
////////////////////////////////////////////////////////////////
class BinarySearchApp
{
public static void main(String[] args)
{
int maxSize = 100; // array size
ordArray arr; // reference to array
arr = new ordArray(maxSize); // create the array
arr.insert(72); // insert items
arr.insert(90);
arr.insert(45);
arr.insert(126);
arr.insert(54);
arr.insert(99);
arr.insert(144);
arr.insert(27);
arr.insert(135);
arr.insert(81);
arr.insert(18);
arr.insert(108);
arr.insert(9);
arr.insert(117);
arr.insert(63);
arr.insert(36);
arr.display(); // display array
int searchKey = 27; // search for item
if( arr.find(searchKey) != arr.size() )
System.out.println("Found " + searchKey);
else
System.out.println("Can't find " + searchKey);
} // end main()
} // end class BinarySearchApp
////////////////////////////////////////////////////////////////
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
《4》 漢諾塔問題
// towers.java
// solves Towers of Hanoi puzzle
// to run this program: C>java TowersApp
////////////////////////////////////////////////////////////////
class TowersApp
{
static int nDisks = 3;
public static void main(String[] args)
{
doTowers(nDisks, 'A', 'B', 'C');
}
//-----------------------------------------------------------
public static void doTowers(int topN,
char src, char inter, char dest)
{
if(topN==1)
System.out.println("Disk 1 from " + src + " to "+ dest);
else
{
doTowers(topN-1, src, dest, inter); // src to inter
System.out.println("Disk " + topN + // move bottom
" from " + src + " to "+ dest);
doTowers(topN-1, inter, src, dest); // inter to dest
}
}
//-------------------------------------------------------------
} // end class TowersApp
////////////////////////////////////////////////////////////////
《5》歸併排序 歸併兩個有序數組
// merge.java
// demonstrates merging two arrays into a third
// to run this program: C>java MergeApp
////////////////////////////////////////////////////////////////
class MergeApp
{
public static void main(String[] args)
{
int[] arrayA = {23, 47, 81, 95};
int[] arrayB = {7, 14, 39, 55, 62, 74};
int[] arrayC = new int[10];
merge(arrayA, 4, arrayB, 6, arrayC);
display(arrayC, 10);
} // end main()
//-----------------------------------------------------------
// merge A and B into C
public static void merge( int[] arrayA, int sizeA,
int[] arrayB, int sizeB,
int[] arrayC )
{
int aDex=0, bDex=0, cDex=0;
while(aDex < sizeA && bDex < sizeB) // neither array empty
if( arrayA[aDex] < arrayB[bDex] )
arrayC[cDex++] = arrayA[aDex++];
else
arrayC[cDex++] = arrayB[bDex++];
while(aDex < sizeA) // arrayB is empty,
arrayC[cDex++] = arrayA[aDex++]; // but arrayA isn't
while(bDex < sizeB) // arrayA is empty,
arrayC[cDex++] = arrayB[bDex++]; // but arrayB isn't
} // end merge()
//-----------------------------------------------------------
// display array
public static void display(int[] theArray, int size)
{
for(int j=0; j<size; j++)
System.out.print(theArray[j] + " ");
System.out.println("");
}
//-----------------------------------------------------------
} // end class MergeApp
////////////////////////////////////////////////////////////////
(6)歸併排序 ---- 利用遞歸的思想
// mergeSort.java
// demonstrates recursive merge sort
// to run this program: C>java MergeSortApp
////////////////////////////////////////////////////////////////
class DArray
{
private long[] theArray; // ref to array theArray
private int nElems; // number of data items
//-----------------------------------------------------------
public DArray(int max) // constructor
{
theArray = new long[max]; // create array
nElems = 0;
}
//-----------------------------------------------------------
public void insert(long value) // put element into array
{
theArray[nElems] = value; // insert it
nElems++; // increment size
}
//-----------------------------------------------------------
public void display() // displays array contents
{
for(int j=0; j<nElems; j++) // for each element,
System.out.print(theArray[j] + " "); // display it
System.out.println("");
}
//-----------------------------------------------------------
public void mergeSort() // called by main()
{ // provides workspace
long[] workSpace = new long[nElems];
recMergeSort(workSpace, 0, nElems-1); //第一次調用 開始的腳標0 最大的 nElems-1
}
//-----------------------------------------------------------
private void recMergeSort(long[] workSpace, int lowerBound, int upperBound)
{
if(lowerBound == upperBound) // if range is 1,
return; // no use sorting
else
{ // find midpoint
int mid = (lowerBound+upperBound)/2;
recMergeSort(workSpace, lowerBound, mid); // sort low half
recMergeSort(workSpace, mid+1, upperBound);// sort high half
merge(workSpace, lowerBound, mid+1, upperBound);// merge them
} // end else
} // end recMergeSort()
//-----------------------------------------------------------
private void merge(long[] workSpace, int lowPtr, int highPtr, int upperBound)
{
int j = 0; // workspace index
int lowerBound = lowPtr;
int mid = highPtr-1;
int n = upperBound-lowerBound+1; // # of items
while(lowPtr <= mid && highPtr <= upperBound)
if( theArray[lowPtr] < theArray[highPtr] )
workSpace[j++] = theArray[lowPtr++];
else
workSpace[j++] = theArray[highPtr++];
while(lowPtr <= mid)
workSpace[j++] = theArray[lowPtr++];
while(highPtr <= upperBound)
workSpace[j++] = theArray[highPtr++];
for(j=0; j<n; j++)
theArray[lowerBound+j] = workSpace[j];
} // end merge()
//-----------------------------------------------------------
} // end class DArray
////////////////////////////////////////////////////////////////
class MergeSortApp
{
public static void main(String[] args)
{
int maxSize = 100; // array size
DArray arr; // reference to array
arr = new DArray(maxSize); // create the array
arr.insert(64); // insert items
arr.insert(21);
arr.insert(33);
arr.insert(70);
arr.insert(12);
arr.insert(85);
arr.insert(44);
arr.insert(3);
arr.insert(99);
arr.insert(0);
arr.insert(108);
arr.insert(36);
arr.display(); // display items
arr.mergeSort(); // merge sort the array
arr.display(); // display items again
} // end main()
} // end class MergeSortApp
////////////////////////////////////////////////////////////////