• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            那誰的技術博客

            感興趣領域:高性能服務器編程,存儲,算法,Linux內核
            隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
            數據加載中……

            二分查找算法(迭代和遞歸版本)

            Bentley在他的著作《Writing Correct Programs》中寫道,90%的計算機專家不能在2小時內寫出完全正確的二分搜索算法。
            我自己嘗試了一下,確實要第一次就完全寫正確不容易.以下兩份實現依次為迭代和遞歸版本的代碼,二分查找的思想很多人都清楚,但是這里有一個細節就是要注意邊界的選擇.


            int search(int array[], int n, int v)
            {
                
            int left, right, middle;

                left 
            = 0, right = n - 1;

                
            while (left <= right)
                {
                    middle 
            = (left + right) / 2;
                    
            if (array[middle] > v)
                    {
                        right 
            = middle - 1;
                    }
                    
            else if (array[middle] < v)
                    {
                        left 
            = middle + 1;
                    }
                    
            else
                    {
                        
            return middle;
                    }
                }

                
            return -1;
            }

            int search_recurse(int array[], int low, int high, int v)
            {
                
            int middle;

                middle 
            = (low + high) / 2;

                
            if (low < high)
                {
                    
            if (array[middle] > v)
                    {
                        
            return search_recurse(array, low, middle, v);
                    }
                    
            else if (array[middle] < v)
                    {
                        
            return search_recurse(array, middle + 1, high, v);
                    }
                    
            else
                    {
                        
            return middle;
                    }
                }
                
            else if (low == high)
                {
                    
            if (array[middle] == v)
                    {
                        
            return middle;
                    }
                    
            else
                    {
                        
            return -1;
                    }

                }
                
            else
                {
                    
            return -1;
                }

                
            return -1;
            }

            int main()
            {
                
            int array[] = {012345671319};

                
            int m = search(array, sizeof(array)/sizeof(array[0]), 13);

                printf(
            "m = %d\n", m);

                m 
            = search_recurse(array, 0sizeof(array)/sizeof(array[0])13);

                printf(
            "m = %d\n", m);

                
            return 0;
            }


            posted on 2009-02-28 19:36 那誰 閱讀(18331) 評論(15)  編輯 收藏 引用 所屬分類: 算法與數據結構

            評論

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            二分查找原理簡單,甚至小學生都能明白。不過這查找算法好多大學生都寫不好。沒辦法,編程這東西,很討厭。不過,要吃飯呵。
            2009-03-01 13:58 |

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            應該是sizeof(array)/sizeof(array[0])
            2009-03-01 14:46 | 阿郎

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            其實,上面的代碼還是有問題——兩個int值相加可能溢出。。。
            2009-03-01 22:19 | Joshua Zhu

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            middle = (low + high) / 2;
            這個變成 middle = low + ((hight - low) / 2), 在代碼之美里看到的。
            其實這樣也行吧。 middle = low/2 + hight/2 就是慢一點兩次除法運算
            2009-03-05 19:08 | reeze

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            @reeze:
            同學,middle = low/2 + hight/2是不對滴。因為它的效果相當于 floor(low / 2) + floor(hight / 2)。
            2009-03-07 09:44 | Joshua Zhu

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            search_recurse(array, low, middle, v);
            這句可以改成
            search_recurse(array, low, middle-1, v);
            吧?
            2009-09-20 23:42 | fzj

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            你的迭代法也不對
            2010-09-09 11:15 | 錢文武

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            學習了
            2011-04-14 18:49 | bubble

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            這個實現有BUG,找不到第一個和最后一個數據,最后不應該RETURN -1,應該再比較一次
            2011-12-08 20:30 | zlc

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            把 int search_recurse(int array[], int low, int high, int v)中的
            else if (low == high)
            {
            if (array[middle] == v)
            {
            return middle;
            }
            else
            {
            return -1;
            }

            }
            else
            {
            return -1;
            }
            去掉,接著把上面的if (low < high)的if改為while,一樣可以執行。

            完整代碼:
            int search_recurse(char *arr,int value,int n)
            {
            int min = 0; //設置最小值為0
            int max = n - 1; //設置最大值為n - 1;
            int mid;
            int pos = -1; //位置初始化為-1
            while(min < max)
            {
            mid = min + (max - min)/ 2; //將字符串折半
            if(arr[mid] > value) //如果中間的值大于要查找的值,則在小的一半中查找
            max = mid - 1;
            else if(arr[mid] < value) //如果中間的值小于要查找的值,則在大的一半中查找
            min = mid + 1;
            else //如果找到記錄下位置
            {
            pos = mid;
            max = mid - 1; //再在小的一半中繼續查找
            }
            }
            if(arr[min] == value) //如果是第一個字符等于要查找的值,記下位置
            pos = min;
            return pos; //返回值
            }
            2012-03-16 21:31 | 莫蕭

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            上面的“完整代碼”部分手誤復制錯了。不過這段代碼也是可行的,不是遞歸而已。
            本來的完整代碼代碼:

            int search_recurse(int arr[], int low, int high, int key)
            {
            int mid;

            mid = (low + high) / 2;
            while (low < high)
            {
            if (arr[mid] > key)
            {
            return BinSearch(arr, low, mid, key);
            }
            else if (arr[mid] < key)
            {
            return BinSearch(arr, mid + 1, high, key);
            }
            else
            {
            return mid;
            }
            }

            return -1;
            }
            2012-03-16 21:34 | 莫蕭

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            @zlc
            博主在循環條件中使用的是“<=”,是可以遍歷到第一個和最后一個元素的。
            2012-10-05 09:57 | 孫磊磊

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            測試環境:vs2005+XP
            // test.cpp : 定義控制臺應用程序的入口點。
            //
            #include "stdafx.h"
            #include <conio.h>
            #include <cstdlib>
            #include <stdlib.h>
            #include <iostream>
            #include <bitset> //為了能夠用std::bitset
            #include <limits>

            #include <time.h>
            using namespace std;


            #include<assert.h>

            //二分查找算法,前提是這個數組要是排好序的!
            //先假設是int數組,返回值表示數組的下標。
            //(1)迭代算法
            int gezb_bsearch(int Source[], int Len, int Key)
            {
            int low=0,high=Len-1;
            while(low<=high)
            {
            std::cout<<"low["<<low<<"]="<<Source[low]<<",high["<<high<<"]="<<Source[high]<<std::endl;
            //if (Key<Source[low] || Key>Source[high])
            //{
            // std::cout<<"can't find ! key="<<Key<<",low["<<low<<"]="<<Source[low]<<",high["<<high<<"]="<<Source[high]<<std::endl;
            // break;
            //}
            int middle = (low + high)/2;
            if (Key==Source[middle])
            {
            std::cout<<"ok get it. \ncurIndex="<<middle<<", key="<<Key<<std::endl;
            return middle;
            }
            else if (Key>Source[middle])
            {
            low = middle+1;
            }
            else if (Key<Source[middle])
            {
            high = middle-1;
            }
            }
            return -1;
            }

            //(2)遞歸算法
            int gezb_bsearch_recurse(int Source[],int Low,int High,int Key)
            {
            int middle;
            if (Low<=High)
            {
            std::cout<<"low["<<Low<<"]="<<Source[Low]<<",high["<<High<<"]="<<Source[High]<<std::endl;
            middle = (Low+High)/2;
            if (Source[middle]==Key)
            {
            std::cout<<"ok get it. \ncurIndex="<<middle<<", key="<<Key<<std::endl;
            return middle;
            }
            else if (Source[middle]>Key)
            {
            return gezb_bsearch_recurse(Source,Low,middle-1,Key);
            }
            else if (Source[middle]<Key)
            {
            return gezb_bsearch_recurse(Source,middle+1,High,Key);
            }
            }
            return -1;
            }


            #define MAXLEN 10000
            void main(void)
            {
            int arr[MAXLEN];
            memset(arr,0,sizeof(arr));
            for (int i=0;i<MAXLEN;++i)
            {
            arr[i]=(i+1)*2;
            }
            int key=arr[7777];
            int iLen = sizeof(arr) / sizeof(arr[0]);

            #if 0
            //迭代算法
            int index = gezb_bsearch(arr,iLen-1,key);
            std::cout<<index<<std::endl;
            #endif

            #if 1
            //遞歸算法
            int index = gezb_bsearch_recurse(arr,0,iLen-1,key);
            std::cout<<index<<std::endl;
            #endif

            system("PAUSE");
            }

            2013-03-31 01:18 | gezb

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            有問題請與我聯系。qq:275916517
            2013-03-31 01:20 | gezb

            # re: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            針對迭代算法的調用處稍做修改:
            #if 0
            //迭代算法
            int index = gezb_bsearch(arr,iLen,key);//之前iLen-1是錯誤的!!!
            std::cout<<index<<std::endl;
            #endif
            2013-03-31 02:05 | gezb
            亚洲第一永久AV网站久久精品男人的天堂AV | 亚洲欧美日韩中文久久 | 久久se这里只有精品| 久久精品这里热有精品| 国产精品99久久久久久宅男 | 一本大道久久香蕉成人网| 久久91精品国产91| 77777亚洲午夜久久多喷| 香蕉久久一区二区不卡无毒影院| 久久国产三级无码一区二区| 久久天天躁夜夜躁狠狠躁2022| 久久99热狠狠色精品一区| 久久久久亚洲AV成人网人人软件| 精品久久久久久久国产潘金莲| 精品久久久久久综合日本| 中文成人无码精品久久久不卡| 无码伊人66久久大杳蕉网站谷歌 | 久久久久九九精品影院| 久久久久免费看成人影片| 久久久久亚洲精品中文字幕| 久久久无码人妻精品无码| 亚洲精品tv久久久久| 91精品免费久久久久久久久| 久久久久久久亚洲Av无码| 99蜜桃臀久久久欧美精品网站| 一本伊大人香蕉久久网手机| 精品久久无码中文字幕| 99久久精品国产一区二区| 国产高潮久久免费观看| 国内精品久久国产大陆| 久久99精品久久久久久hb无码| 亚洲精品国精品久久99热一| 亚洲欧美成人久久综合中文网| 久久99精品久久久久久9蜜桃| 久久免费高清视频| 一级做a爱片久久毛片| 丰满少妇人妻久久久久久4| 人人狠狠综合久久亚洲婷婷| 精品国产福利久久久| 中文字幕亚洲综合久久| 国产精品熟女福利久久AV |