• <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小時內寫出完全正確的二分搜索算法。
            我自己嘗試了一下,確實要第一次就完全寫正確不容易.以下兩份實現(xiàn)依次為迭代和遞歸版本的代碼,二分查找的思想很多人都清楚,但是這里有一個細節(jié)就是要注意邊界的選擇.


            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: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            這個實現(xiàn)有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,一樣可以執(zhí)行。

            完整代碼:
            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; //再在小的一半中繼續(xù)查找
            }
            }
            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
            博主在循環(huán)條件中使用的是“<=”,是可以遍歷到第一個和最后一個元素的。
            2012-10-05 09:57 | 孫磊磊

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

            測試環(huán)境: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: 二分查找算法(迭代和遞歸版本)  回復  更多評論   

            有問題請與我聯(lián)系。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成人网| 亚洲欧洲精品成人久久曰影片 | 久久久久久综合一区中文字幕| 97久久香蕉国产线看观看| 国产99久久久国产精免费| 久久久精品国产| 亚洲国产成人久久精品影视| 久久高潮一级毛片免费| 热re99久久6国产精品免费| 国产女人aaa级久久久级| 亚洲中文精品久久久久久不卡| 国产成人精品久久亚洲高清不卡| 欧美精品乱码99久久蜜桃| 国产ww久久久久久久久久| 久久精品中文闷骚内射| 久久精品极品盛宴观看| 国内精品久久久久影院网站| 久久久久亚洲av无码专区导航| 欧美日韩成人精品久久久免费看| 国产精品久久久久久吹潮| 一级女性全黄久久生活片免费| 久久99精品国产麻豆宅宅| 无码人妻久久久一区二区三区| 久久亚洲国产成人精品无码区| 久久香蕉国产线看观看99 | 久久久久久亚洲精品成人| 无码人妻久久一区二区三区蜜桃| 精品久久久久久| aaa级精品久久久国产片| 亚洲精品高清国产一线久久| 欧美一区二区久久精品| 久久综合伊人77777| 国产精品成人99久久久久91gav| 亚洲成人精品久久| 99久久伊人精品综合观看| 久久久久综合网久久| 国产亚洲美女精品久久久久狼|