算法前戏 递归 二分查找 列表查找

一、递归

概念:

  函数直接或者间接的调用自身算法的过程,则该函数称为递归函数。在计算机编写程序中,递归算法对解决一大类问题是十分有效的。

特点:

  ①递归就是在过程或者函数里调用自身

  ②在使用递归策略时,必须有一个明显的结束条件,称为递归出口。问题规模相比上次递归有所减少,

  ③递归算法解题通常显得很简洁,但递归算法解题的效率较低。所以一般不倡导使用递归算法设计程序。

  ④在递归调用的过程当中系统的每一层的返回点、局部变量等开辟了栈来存储。递归函数次数过多容易造成栈溢出等。

  所以一般不倡导用递归算法设计程序。

要求:

递归算法所体现的"重复"一般有三个条件:

  ①每次在调用规模上都有所缩小(通常是减半)。

  ②相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。

  ③在问题的规模极小时必须用直接解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),

无条件的递归调用将会成为死循环而不能正常结束。

分析以下函数的执行过程:

def func3(x):
    if x>0:
        print(x)
        func3(x-1)

func3(5)

def func4(x):
    if x>0:
         func4(x-1)
         print(x)

func4(5)

  根据Python执行的过程,及函数调用去分析执行结果!

 关于斐波拉契数列

  斐波拉契数列指的是这样一个数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368。

特别注意:第0项是0,第1项是第一个1。这个数列从第2项开始,每一项都等于前两项之和。

def fibo(n):
    before = 0
    after = 1
    if n == 0 or n == 1:
        return n

    if n <= 3:
        return 1
    return fibo(n-1)+fibo(n-2)

print(fibo(3))

斐波那契数列

二分查找

  从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半。

特点:

  二分查找算法就是不断将数组进行对半分割,每次拿中间元素和要找的元素进行比较。小就向右找,大就向左找!

要求:  

  在一段数字内,找到中间值,判断要找的值和中间值大小的比较。
    如果中间值大一些,则在中间值的左侧区域继续按照上述方式查找。
    如果中间值小一些,则在中间值的右侧区域继续按照上述方式查找。
  直到找到我们希望的数字。

def search_data(data,data_find):
    # 中间值的索引号的定义:数组长度/2
    mid = int(len(data)/2)
    # 判断从1开始的数字数组内查找
    if data[mid] >= 1:
        # 如果我们要找的值(data_find)比中间值(data[mid])小
        if data[mid] > data_find:
            print("你要找的数字比中间值[%s]小..." % data[mid])
            # 在中间值(data[mid])的左侧继续查找,在此函数中继续循环
            search_data(data[:mid],data_find)
        # 如果我们要找的值(data_find)比中间值(data[mid])大
        elif data[mid] < data_find:
            print("你要找的数字比中间值[%s]大..." % data[mid])
            # 在中间值(data[mid])的右侧继续查找,在此函数中继续循环
            search_data(data[mid:],data_find)
        else:
            # 如果我们要找的值(data_find)既不比中间值(data[mid])大,也不比中间值(data[mid])小,则就是它
            print("这就是你要找的[%s]!" % data[mid])
    else:
        print("不好意思,没有找到你要的值...")

if __name__ == ‘__main__‘:
    # 创建一个1到6000万的连续数字数组
    data = list(range(60000000))
    # 调用函数找到95938的值
    search_data(data,95938)

相关代码举例

列表查找

列表查找:从列表中查找指定元素
  输入:列表、待查找元素
  输出:元素下标或未查找到元素

一般是有两种方法:

1、顺序查找

  从列表第一个元素开始,顺序进行搜索,直到找到为止。

def linear_search(data_set,value):
    for i in data_set:
        if data_set[i] == value:
            return i

2、二分查找

  从有序列表的候选区data[0:n]开始,通过对待查找的值与候选区中间值的比较,可以使候选区减少一半。

def bin_search(data_set,value):
    low = 0
    high = len(data_set)-1
    while low <= high:
        mid = (low+high)//2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] > value:
            high = mid - 1
        else:
            low = mid + 1

def bin_search(data_set,value,low,high):
    if low <= high:
        mid = (low+high)//2
        if data_set[mid] == value:
            return mid
        elif data_set[mid] >value:
            return bin_search(data_set,value,low,high)
        else:
            return bin_search(data_set, value, low, high)
    else:
        return

二分查找递归版

练习题:

现有一个学员信息列表(按id增序排列),格式为:
	[
		{"id":1001, "name":"张三", "age":20},
		{"id":1002, "name":"李四", "age":25},
		{"id":1004, "name":"王五", "age":23},
		{"id":1007, "name":"赵六", "age":33}
	]

修改二分查找代码,输入学生id,输出该学生在列表中的下标,并输出完整学生信息。
l = [
    {"id":1001, "name":"张三", "age":20},
    {"id":1002, "name":"李四", "age":25},
    {"id":1004, "name":"王五", "age":23},
    {"id":1007, "name":"赵六", "age":33}
]

def bin_search(data_set,value):
    """
    二分查找
    :param data_set: 列表
    :param value: 要查的值
    :return:
    """
    low = 0
    high = len(data_set)-1
    while low <= high:
        mid = (low+high)//2
        if data_set[mid][‘id‘] == value:
            return (mid,data_set[mid])
        elif data_set[mid][‘id‘] > value:
            high = mid - 1
        else:
            low = mid + 1
    else:
        return (0,None)

flog = True
while flog:
    sid = input("请输入学号(退出:Q):").strip()
    if sid.isdigit():
        if sid.upper() == "Q":
            flog = False
        else:
            sid = int(sid)
            mid,infos = bin_search(l,sid)
            if not infos:
                print("查无此人!!!")
            else:
                s = "学生学号:{id},姓名:{name},年龄:{age}".format(**infos)
                print("该学生所在信息索引坐标:%s"%mid)
                print("该学生的所有信息:%s"%s)
时间: 2024-12-25 18:58:24

算法前戏 递归 二分查找 列表查找的相关文章

【算法拾遗】二分查找递归非递归实现

转载请注明出处:http://blog.csdn.net/ns_code/article/details/33747953 本篇博文没太多要说的,二分查找很简单,也是常见常考的查找算法,以下是递归非递归的实现. 非递归实现: /* 非递归实现,返回对应的序号 */ int BinarySearch(int *arr,int len,int key) { if(arr==NULL || len<1) return -1; int low = 0; int high = len-1; while(l

二分查找算法(递归与非递归两种方式)

首先说说二分查找法. 二分查找法是对一组有序的数字中进行查找,传递相应的数据,进行比较查找到与原数据相同的数据,查找到了返回1,失败返回对应的数组下标. 采用非递归方式完成二分查找法.java代码如下所示. /* * 非递归二分查找算法 * 参数:整型数组,需要比较的数. */ public static int binarySearch(Integer[]srcArray,int des){ //第一个位置. int low=0; //最高位置.数组长度-1,因为下标是从0开始的. int h

Python 迭代器&amp;生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发

本节大纲 迭代器&生成器 装饰器  基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )等类似公式后,必须自己解析里面的(),+,-,*,/符号和公式,运算后得出结果,结果必须与真实的计算器所得出的结果一致 迭代器&

算法——基础篇——二分查找

     二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.     首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功

二分查找/折半查找算法

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表中间位置记录的关键字与查找关键字比较,如果两者相等,则查找成功:否则利用中间位置记录将表分成前.后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表.重复以上过程,直到找到满足条件的记录,使查找成功,或直到子表不存在为止,此时查找不成功. class Pr

列表查找以及二分查找

列表查找:从列表中查找指定元素 输入:列表.待查找元素 输出:元素下标或未查找到元素 list1=[1,3,4,5,6,8,9,12,15,20] print(list1.index(8)) def listSearch(list,num): i=0 while i<len(list)-1: if list[i]==num: return i else: i=i+1 return None 二分查找 二分查找的前提是列表是有序的 def search(arr,num): low=0 high=l

列表查找及二分查找

1. 查找算法 描述顺序查找与二分法(折半搜索)的概念以及用python实现其查找流程 一.顺序查找 1. 什么是顺序查找 当数据存储在诸如列表的集合中时,我们说这些数据具有线性或顺序关系. 每个数据元素都存储在相对于其他数据元素的位置. 由于这些索引值是有序的,我们可以按顺序访问它们. 这个过程产实现的搜索即为顺序查找. 2. 顺序查找原理剖析: 从列表中的第一个元素开始,我们按照基本的顺序排序,简单地从一个元素移动到另一个元素,直到找到我们正在寻找的元素或遍历完整个列表.如果我们遍历完整个列

9.算法之顺序、二分、hash查找

9.算法之顺序.二分.hash查找 一.查找/搜索 - 我们现在把注意力转向计算中经常出现的一些问题,即搜索或查找的问题.搜索是在元素集合中查找特定元素的算法过程.搜索通常对于元素是否存在返回 True 或 False.有时它可能返回元素被找到的地方.我们在这里将仅关注成员是否存在这个问题. - 在 Python 中,有一个非常简单的方法来询问一个元素是否在一个元素列表中.我们使用 in 运算符. >>> 15 in [3,5,2,4,1] False >>> 3 in

冒泡排序,递归二分查找法,二分查找法

#冒泡排序list1=[2,4,5,6,7,8,9,11,30,35,38,41,42] def bubble_sort(list): for i in range(len(list)-1): for j in range(len(list)-1-i): if list[j]>list[j+1]: list[j],list[j+1]=list[j+1],list[j] print(list) list1=[2,4,55,6,78,38,95,11,30,35,38,41,42] bubble_s