小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

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

 herowuking 2015-10-10

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

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

還是考慮上面的兩個(gè)條件:

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

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

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

接著考慮條件二:簡(jiǎn)單情境是什么呢?

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

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

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請(qǐng)輸入要查找的數(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}

程序運(yùn)行結(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請(qǐng)輸入要查找的數(shù)字:20
4mid=26
5key 20 比 data[mid-1] 25 小,取前半段
6mid=20
7key 20 比 data[mid-1] 17 大,取后半段
8mid=23
91

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

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多