python算法之二分查找

说明:大部分代码是在网上找到的,好几个代码思路总结出来的

通常写算法,习惯用C语言写,显得思路清晰。可是假设一旦把思路确定下来,并且又不想打草稿。想高速写下来看看效果,还是python写的比較快。也看个人爱好。实习的时候有个同事对于python的缩进来控制代码块各种喷。。。。他认为还是用大括号合适。。。怎么说呢,适合自己的才是最好的。我个人的毛病就是,写了几天C,到要转到python的时候,代码中依旧有C的影子。。比方大括号问题,比方忘记在while或这for、if、else等后面加“:”。而假设写了几天Python,要转到C的时候。会忘记声明一些变量。直接拿来就用。执行的时候,各种变量没有定义。在这里给自己提个醒。多思考也要多动手。

今天无意中看到了二分查找。本来以为非常easy的代码。几行就结束了,后来看到了一个比較牛的代码。才发现人比人该死是永恒的真理。为了不该死,也要把不该死的代码学会才行啊,二分查找的原理非常easy,就是在一个有序序列中。查找代码是一半一半的比較而不是一个一个的比較

最简单的二分查找非递归代码例如以下:

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;
        }
        else if (array[middle] < v)
        {
            left = middle;
        }
        else
        {
            return middle;
        }
    }

    return -1;
}

输入:array数组。array大小n,查找元素v

输出:v的所在位置,没有找到返回-1

#####################################################################################################################################

以下写个递归的代码:

#include<stdio.h>

int search(int arr[],int low,int high,int key)
{
        int mid = (low+high)/2;
        if(low > high)
                return -1;
        if(arr[mid] == key)
                return mid;
        else if(arr[mid]>key)
                return search(arr,low,mid-1,key);
        else
                return search(arr,mid+1,high,key);
}
int main()
{
        int arr[101] = {1,2,3,4,87,90,100};
        int low = 0,high = 8,key = 87,ret;
        ret = search(arr,low,high,key);
        if(ret != -1)
                printf("the return is %d",ret);
        else
                printf("FBI warning:the return is -1,not find the key");
}

不知道递归的同学。请參考递归的吐槽。。。如图:当年第一次听到老师说递归的时候,想的就是这个

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcmVjc3lzbWw=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" >

可是事实上递归是这种

好了不扯了。二分查找这个代码事实上细致看的话还是有点问题的。比方说这个三次推断。两次比較。还有就是

在循环体内,计算中间位置的时候,使用的是这个表达式:

mid = (left + right) / 2;

假如,left与right之和超过了所在类型的表示范围的话,那么middle就不会得到正确的值.

所以,更稳妥的做法应该是这种:

mid = left + (right - left) / 2;

那我们优化一下,python代码例如以下:

def search(arr,n,v):
        left = -1
        right = n
        while(left+1 != right):
                mid = left+(right-left)/2
                if(arr[mid] < v):
                        left = mid
                else:
                        right = mid
        if(right >= n or arr[right] != v):
                right = -1
        return right
if __name__ == '__main__':
        arr = [1,2,4,23,87,90,555,1222,1444]
        n = len(arr)
        ret = search(arr,n,87)
        print ret

看C的代码:

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

    left = -1, right = n;

    while (left + 1 != right)
    {
        mid = left + (right - left) / 2;

        if (array[mid] < v)
        {
            left = mid;
        }
        else
        {
            right = mid;
        }
    }

    if (right >= n || array[right] != v)
    {
        right = -1;
    }

    return right;
}

这个代码先不说理不理解,光返回值仅仅用right这个就非常牛逼,这样看着非常easy,可是非常精髓的感觉有没有?再看while的推断,left+1!=right是不是非常正点?自己理解ba

时间: 2024-10-26 22:00:24

python算法之二分查找的相关文章

查找算法:二分查找、顺序查找

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活.此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205 查找算法 查找算法是在存在的序列(list) 中查找特定的目标(target),要求序列中每个记录必须与一个关键词(key)关联才能进行查找. 查找算法通常需要两个输入: 1.被查找的序列 2.要查找的关键词 查找算法的输出参数和返回值: 1.返回类型为 Error_co

【数据结构与算法】二分查找

基本思想 首先将给定的值K与表中中间位置元素比较,若相等,则查找成功:若不等,则所需查找的元素只能在中间数据以外的前半部分或者后半部分,缩小范围后继续进行同样的查找,如此反复,直到找到为止. 代码实现 /** * 源码名称:BinarySearch.java * 日期:2014-08-14 * 程序功能:二分查找 * 版权:[email protected] * 作者:A2BGeek */ public class BinarySearch { public static int binaryS

算法系列&lt;二分查找&gt;

二分查找又称折半查找,是针对有序顺序表的查找,前提:数据是顺序存储的,已经按照关键词进行升序排序.查找成功返回索引值,查找不成功返回-1. 下面用java来实现二分查找算法: /** * 二分查找:针对已排好序的序列,查找成功返回所在位置的索引值,查找不成功返回-1 * 查找的最好时间复杂度:O(1),最坏时间复杂度O(logN),平均时间复杂度:O(logN) * 测试case: * case1:{1} 查找1 * case2:{1} 查找2 * case3:{} 查找1 * case4:{1

算法学习——二分查找(折半查找)

算法学习--二分查找 注意点 1. 二分查找的前提是有序的数组 2. 建议使用[start,end)的区间寻找,符合规范 3. 使用的是递归法 递归的人口 private static int find(int[] temp, int x) { //如果要查找的数x比数组的最后一个数要大,则找不到数值,返回-1 if (x > temp[temp.length - 1]) { return -1; } return find(temp, 0, temp.length, x);//进入递归 } 递

常见算法之二分查找

1.算法思想 二分查找采用分而治之的思想.要求被查找的集合必须是有序的.主要思路: 根据起始位置和结束位置,确定中间位置. 拿目标值与中间位置的值做比较,假如目标值大于中间位置取值,则起始位置为中间位置加1. 假如目标值小于中间位置取值,则结束位置为中间位置减1. 直至起始位置小于等于结束位置,找到目标值的位置即索引. 2.代码实现 2.1.基于Python3.x实现 代码如下: 1 #coding:utf-8 2 def half_search(lst,key): 3 start = 0 4

Python——递归、二分查找算法

递归函数 1. 递归 (1)什么是递归:在函数中调用自身函数(2)最大递归深度:默认997/998--是Python从内存角度出发做的限制 n = 0 def story(): global n n+= 1 print(n) story() #997/998 story() (3)修改最大深度:最好不要改--递归次数太多,则不适合用递归解决问题 import sys sys.setrecursionlimit(2000) #1997/1998 2. 递归的优点 会让代码变简单 3. 递归的缺点

python之路——二分查找算法

楔子 如果有这样一个列表,让你从这个列表中找到66的位置,你要怎么做? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88] 你说,so easy! l.index(66)... 我们之所以用index方法可以找到,是因为python帮我们实现了查找方法.如果,index方法不给你用了...你还能找到这个66么? l = [2,3,5,10,15,16,18,22,26,30,32,35,41,

python几种排序算法和二分查找方法的实现

一.算法概念 - 含义:算法就是对问题进行处理且求解的一种实现思路或者思想. 评判程序优劣的方法 - 消耗计算机资源和执行效率(无法直观) 计算算法执行的耗时(不推荐,因为会受机器和执行环境的影响) 时间复杂度(推荐) 时间复杂度 - 评判规则:量化算法执行的操作/执行步骤的数量, - 如下列 def sumOfN(n): # 执行一步: theSum = 0 for i in range(1,n+1): # 下式一共执行n步,for循环不算一步,因为它是控制循环次数的 theSum = the

python常用的简单算法,二分查找、冒泡排序、数组翻转等

1.二分查找:主要用于查询元素数量较多的列表,采用二分查找,取中位值,进行大小比较,可以提高效率 1 #二分查找,用于在较大的数据列表中查询某个值,考虑到元素比较多,单纯的遍历会造成内存压力过大,考虑使用二分查找 2 #二分查找的关键在于查询中间值,将需要查找的值与中间值进行比较,然后确定查找方向 3 def binary_search(data_source,find_n): 4 #取中位数 5 mid=int(len(data_source)/2) 6 7 if len(data_sourc