算法-遞歸分治(經典例子)

* Xcode中完成

遞歸(recursion):程序調用自身的編程技巧。

遞歸滿足2個條件:

1)有反覆執行的過程(調用自身)

2)有跳出反覆執行過程的條件(遞歸出口)

例子:

(1) 階乘:

 n! = n * (n-1) * (n-2) * ...* 1(n>0)
int recursion(int value) {

    if(value ==0) {
        return 1;
    }else if(value >0) {
        return  value * recursion(value -1);
    }else {
        return 0;
    }
}
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        NSLog(@"3!=%d",recursion(3));
    }
    return 0;
}

(2) 全排列
從n個不同元素中任取m(m≤n)個元素,按照一定的順序排列起來,叫做從n個不同元素中取出m個元素的一個排列。當m=n時所有的排列情況叫全排列。

如1,2,3三個元素的全排列爲:

1,2,3

1,3,2

2,1,3

2,3,1

3,1,2

3,2,1

#import <Foundation/Foundation.h>

//交換函數
void swap( int *a , int *b)
{
    int temp ;
    temp = *a;
    *a=*b;
    *b=temp;
}
//排列函數
void perm(int list[], int begin, int k,int m)
{
    if (k == m) {
        for (int i = begin;i<=m; i++) {
            printf("%d,",list[i]);
        }
        printf("\n");
    }else{
        for (int i=k; i<=m; i++) {
            swap(&list[i], &list[k]);
            perm(list, begin,k+1, m);
            swap(&list[i], &list[k]);
        }
    }
}
//調用排列函數,旨在添加一個不變量,紀錄要隨遞歸變化的k值;
//函數意義:列出list數組從第k到第m的全排列(數組從0開始計數)
void permutation(int list[],int k,int m)
{
    perm(list,k , k, m);
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
       int list[5]={1,2,3,4,5};
       permutation(list, 0,2);
    }
    return 0;
}
![運行結果截圖](http://img.blog.csdn.net/20151007200310165)
PS:值交換函數swap函數區別於以下兩種寫法:    
//寫法一:
void swap( int *a , int *b)
{
    int *temp ;
    temp = a;
    a=b;
    b=temp;
}
//這種寫法在函數中改變了兩個指針變量形參的數值,但是沒有將改變後的數值傳遞迴main函數,因此,main函數中不會發生變化

//寫法二:
void swap( int *a , int *b)
{
    int *temp ;
    *temp =* a;
    *a=*b;
    *b=*temp;
}
//*temp代表temp所指向的變量,但是temp並沒有確定的地址值,所以它的值也就不可預見,*temp指向的單元也是不可預見的,因此對*temp賦值可會破壞系統正常工作狀況。應該是將*a的值賦給一個整形變量。

(3)斐波那契數列

斐波納契數列,又稱黃金分割數列,指的是這樣一個數列:1、1、2、3、5、8、13、21、……
這個數列從第三項開始,每一項都等於前兩項之和。
第n項的值即爲fibonacci(n)。

#import <Foundation/Foundation.h>
int fibonacci(int n)
{
    if (n == 0 ) {
        return 0;
    }else if(n ==1){
        return 1;
    }else{
        return fibonacci(n-1)+fibonacci(n-2);
    }
}


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        NSLog(@"%d",fibonacci(4));

    }
    return 0;
}

(4)二分搜索(分治)
給定排好序的數組list[],在數組n個元素中找出特定x,返回其在數組的位置序號。

#import <Foundation/Foundation.h>

//函數意義:在含有n個元素的數組list中查找元素x返回x的序號(-1)代表未找到
int binarySearch (int list[],int n,int x){
    int left=0,right=n-1;
    while ( left <= right ) {
        int mid = (left+right)/2;
        if (x == list[mid]) {
            return mid;
        }else if(x<list[mid] ) {
            right=mid-1;
        }else {
            left=mid+1;
        }
    }
    return -1;
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        int list[5]={1,2,3,4,5};
        int n=5;
        int x=3;
        NSLog(@"%d",binarySearch(list, n, x));

    }
    return 0;
}

(5)快速排序

#import <Foundation/Foundation.h>

void swap( int *a , int *b)
{
    int temp ;
    temp = *a;
    *a=*b;
    *b=temp;
}

//函數意義:從數組list中(從p到r)隨機獲取其中一個數,把小於它的放在它左邊,大於它的放在它右邊,返回最後這個值的位置
int partition(int list[], int p,int r) {

    int randomIndex=(int)random()%(r-p+1);
    int leftTemp=randomIndex-1;
    int rightTemp = randomIndex+1;
    int x=list[randomIndex];
    for (int i=p; i<randomIndex ; i++) {
        if (x<list[i]) {
            swap(&list[i], &list[leftTemp]);
            swap(&list[leftTemp], &list[randomIndex]);
            randomIndex--;
        }
    }for (int i=r ; i>randomIndex; i--) {
        if (x>list[i]) {
            swap(&list[i], &list[rightTemp]);
            swap(&list[rightTemp], &list[randomIndex]);
            randomIndex++;
        }
    }

    return randomIndex;
}
//函數意義:對無序數組的p到r進行從小到大的排序
void quickSort(int list[],int p,int r){
    if(p<r){
        int q=partition(list,p,r);
        quickSort(list, p, q-1);
        quickSort(list, q+1, r);
    }
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        int list[5]={1,5,3,2,4};
        quickSort(list,0,4);
        for (int i=0; i<=4; i++) {
            printf("%d," , list[i]);
        }
    }
    return 0;
}

点赞