日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

漫談遞歸:二分查找算法的遞歸實現(xiàn)

 herowuking 2015-10-10

還有一個典型的遞歸例子是對已排序數(shù)組的二分查找算法。

現(xiàn)在有一個已經(jīng)排序好的數(shù)組,要在這個數(shù)組中查找一個元素,以確定它是否在這個數(shù)組中,很一般的想法是順序檢查每個元素,看它是否與待查找元素相同。這個方法很容易想到,但它的效率不能讓人滿意,它的復(fù)雜度是O(n)的。現(xiàn)在我們來看看遞歸在這里能不能更有效。

還是考慮上面的兩個條件:

  • 第一:這個問題是否可以分解為形式相同但規(guī)模更小的問題?
  • 第二:如果存在這樣一種分解,那么這種分解是否存在一種簡單情境?

考慮條件一:我們可以這樣想,如果想把問題的規(guī)??s小,我們應(yīng)該做什么?

可以的做法是:我們先確定數(shù)組中的某些元素與待查元素不同,然后再在剩下的元素中查找,這樣就縮小了問題的規(guī)模。那么如何確定數(shù)組中的某些元素與待查元素不同呢? 考慮到我們的數(shù)組是已經(jīng)排序的,我們可以通過比較數(shù)組的中值元素和待查元素來確定待查元素是在數(shù)組的前半段還是后半段。這樣我們就得到了一種把問題規(guī)??s小的方法。

接著考慮條件二:簡單情境是什么呢?

容易發(fā)現(xiàn),如果中值元素和待查元素相等,就可以確定待查元素是否在數(shù)組中了,這是一種簡單情境,那么它是不是唯一的簡單情境呢? 考慮元素始終不與中值元素相等,那么我們最終可能得到了一個無法再分的小規(guī)模的數(shù)組,它只有一個元素,那么我們就可以通過比較這個元素和待查元素來確定最后的結(jié)果。這也是一種簡單情境。

好了,基于以上的分析,我們發(fā)現(xiàn)這個問題可以用遞歸來解決,二分法的代碼如下:

01#include "stdio.h"
02#include "stdlib.h"
03 
04void selectionSort(int data[], int count);
05int binary_search(int *a, int n, int key);
06 
07void main()
08{
09    int i, key, rs;
10    int arr[10];
11    int count;
12 
13    printf("排序前數(shù)組為:");
14    srand((int)time(0));
15    for(i=0; i < 10; i++)
16    {
17        arr[i] = rand()%100;
18        printf("%d ",arr[i]);
19    }
20 
21    count = sizeof(arr)/sizeof(arr[0]);
22    selectionSort(arr, count);
23 
24    printf("\n排序后數(shù)組為:");
25    for(i=0; i < 10; i++)
26    {
27        printf("%d ", arr[i]);
28    }
29 
30    printf("\n請輸入要查找的數(shù)字:");
31    scanf("%d",&key);
32 
33    rs = binary_search(arr, 10, key);
34    printf("%d ", rs);
35}
36 
37void selectionSort(int data[], int count)
38{
39    int i, j, min, temp;
40    for(i = 0; i < count; i ++) {
41        /*find the minimum*/
42        min = i;
43        for(j = i + 1; j < count; j ++)
44            if(data[j] < data[min])
45                min = j;
46        temp = data[i];
47        data[i] = data[min];
48        data[min] = temp;
49    }
50}
51 
52int binary_search(int *data, int n, int key)
53{
54    int mid;
55    if(n == 1){
56        return (data[0] == key);
57    }else{
58        mid = n/2;
59        printf("mid=%d\n", data[mid]);
60        if(data[mid-1] == key)
61            return 1;
62        else if(data[mid-1] > key)
63        {
64            printf("key %d 比 data[mid-1] %d 小,取前半段 \n", key, data[mid-1]);
65            return binary_search(&data[0], mid, key);
66        }
67        else
68        {
69            printf("key %d 比 data[mid-1] %d 大,取后半段 \n", key, data[mid-1]);
70            return binary_search(&data[mid], n - mid, key);
71        }
72    }
73}

程序運行結(jié)果:

1排序前數(shù)組為:53 27 26 99 20 17 15 25 23 63
2排序后數(shù)組為:15 17 20 23 25 26 27 53 63 99
3請輸入要查找的數(shù)字:20
4mid=26
5key 20 比 data[mid-1] 25 小,取前半段
6mid=20
7key 20 比 data[mid-1] 17 大,取后半段
8mid=23
91

這個算法的復(fù)雜度是O(logn)的,顯然要優(yōu)于先前提到的樸素的順序查找法。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多