1. 程式人生 > >java資料結構讀書筆記--引論

java資料結構讀書筆記--引論

1 遞迴簡論

需求:求出f(x)=2f(x-1)+x²的值。滿足f(0)=0

public class Recursion {
    // 需求: 求出f(x)=2f(x-1)+x²的值。滿足f(0)=0
    public static void main(String[] args) {
        int f = f(1);
        System.out.println(f);
    }
    public static int f(int x){
        // 1 當x=1的時候f(1)=1 f(0)=0 f(2)=2f(1)+4=6
        if
(x==0) return x; return 2*f(x-1)+x*x; } }

像上面的情況來說。我們知道f(0)=0;如果不知道這個情況,那麼程式將不會計算出來。這種情況稱之為基準情況,也就是說不需要經過遞迴而直接就可以計算出來。這就是基準情況。
接著我們再來看一個情況:如下程式碼所示。

public static int bad(int n){
    if(n==0)
            return 0;
        return bad(n/3+1)+n-1;
}

Exception in thread “main” java.lang.StackOverflowError
at com.gosaint.firstChapter.Introduction.Recursion.bad(Recursion.java:25)
at com.gosaint.firstChapter.Introduction.Recursion.bad(Recursion.java:25)
at com.gosaint.firstChapter.Introduction.Recursion.bad(Recursion.java:25)
程式出現了棧溢位。這是因為沒有基準情況的。當n=1,此時bad(1)。但是bad(1)的值不知道,因此無法繼續遞迴下去。也就是說,遞迴必須要滿足的條件:
a 必須存在基準情況
b 能夠持續不斷的進行單方向的迴圈

需求:計算 一個數N中的二進位制中1的個數:
計算說明:
1 對於一個數,首先將其轉換為二進位制,對於其中1或者0的個數分別可以如下的計算:
n&(n-1):其中計算1的個數
n|(n+1):其中計算出0的個數
詳細的解釋下:如9的二進位制是:1001。其中的1的個數為2。9&8的結果是1000。消除了右邊的1。繼續迴圈消除。從而得到1的個數。
2 對於一個奇數而言,其中二進位制中1的個數為n/2的數中二進位制的個數加1
遞迴的方式計算一個數中二進位制中1的個數

public static int binarySystem(int N){
    if(N%2!=0){
        return
binarySystem(N/2)+1; }else { // 如果N為偶數,二進位制中1的個數計算如下: int n; for ( n=0;N>0;n++){ N&=(N-1); } return n; } }

直接進行計算,不適用遞迴的方式

/**
     * 由於n&(n-1)的這種方式可以直接計算,因此可以不用使用遞迴的方式操作
     * @param N
     * @return
     */
    public static int binarySystem02(int N) {
        int n;
        for (n = 0; N > 0; n++) {
            N &= (N - 1);
        }
        return n;
    }