《python算法教程》个人学习心得之(一):归纳、递归与归简

写在开头:

这个学期上了一门叫做Python入门的选修课,差不多算是系统的学习了一下Python这门编程语言,基本的入门应该可以是算的,下一步的学习当然也不能落下。去图书馆闲逛,看到了这本《python算法教程》(挪威 Magnus Lie Hetland 著 凌杰 陆禹淳 顾俊 译),下一步先温习一下以前的算法也是不错的。本人小透明一枚,写这些,权当是一种学习笔记,如果你无意中看到,并觉得对你的学习有所帮助,对我来说也是一种荣幸。



———————————————————-正文分割————————————————————

前三章的内容,没有什么特别难的,差不多都是一些基本概念的东西,这本书的第四章是叫做“归纳、递归与归简”,这是我们接触的比较早的算法思想之一,先解释一些这三种概念:

归简法指将某一问题转化成另一个问题,通常来讲,我们倾向于把一个较难的未知问题转化成一个较简单的已知问题来进行解决。(把问题简单化)

归纳法是用于证明某个语句读某种大型对象类是否成立,我们要先证明在某一基本情况下成立,然后证明它可以通过一个对象传达到“下一个”对象。(高中时接触到的数学归纳法和高等数学中的归纳法和这种是差不多的)

递归法主要用于函数的自我调用。举个例子,“世界上没有比恐怖本身更恐怖的事情”,或者“大鱼吃小鱼,小鱼吃虾米”。

那下面就归纳法、归简法、递归法举几个算法的实例理解一下;

首先讲一个归简法的例子。

-我们要从某个数字列表中找到两个彼此最接近但不相同的数字(两个数字绝对值差最小)。

最简单的想法,我们可以用双重循环,逐个数字进行减运算,然后取绝对值,每次与当前最小的进行比较,最后肯定可以找到我们想要的两个数字,代码如下:

def get_abs_normol(seq):                     #我们假设数组已经定义好
    d = float("inf")                         #正无穷
    for i in range(seq):                     #双重循环
        for j in range(seq):
            if i == j:
                continue
            d = abs(i-j)
            if d < dd:
                xx, yy, dd = i, j, d
    print(xx)                                #输出结果
    print(yy)
    print(dd)

我们可以分析一下这个问题,我们要找的绝对值相差最小的两个数,在一维的数轴上一定是相邻的两个数,那我们只需对相邻的两个数进行减操作即可。

我们得到另一种解法:先对所需数组进行排序,然后顺序进行减操作,代码如下:

def get_abs_better(seq):
    dd = float("float")
    sel_sort(seq)
    for i in range(len(seq)-1):
        x, y = seq[i],seq[i+1]
        if x == y:
            continue
        d = abs(x-y)
        if(d < dd):
            xx, yy, dd = x, y, d;
    print(xx)
    print(yy)
    print(dd)

这样,我们再去看这个题的解法,就从双重循环优化成单循环,新的算法更快了,这个简单的例子就是归简法的一种应用,类似的还有许多例子,比如拓扑排序(之后如果写图论笔记应该会写)。

递归法应用比较广,记得上数据结构课程的时候,老师讲过,有时候递归的算法,会要求用非递归的方法进行重写,利用栈和循环,即可实现。还是举两个比较简单的例子——排序;

我们来看选择排序:

def sel_sort(seq):                                         #选择排序
    for i in range(len(seq)-1,0,-1): 
        max_j = i                                          #记录"目前最大"的索引
        for j in range(i):                                 #寻找下一个更大的数
            if seq[j] > seq[max_j]:                        #如果找到,就更新
                max_j = j
        seq[i], seq[max_j] = seq[max_j], seq[i]            #把这个数放到它的位置上

选择排序是一个非常经典,并且基础的排序,那么它的递归算法怎么写呢:

def sel_sort_res(seq, i): 
    if(i == 0):
        return
    max_j = i;
    for j in range(len(seq)-1,0,-1):
        max_j = i
        for j in range(i):
            if seq[j] > seq[max_j]:
                max_j = j
        seq[i], seq[max_j] = seq[max_j], seq[i]
        sel_sort_res(seq,i-1)                            #把剩下的进行排序

递归算法有很多中理解方式,我的理解(拿排序来讲),先排完当前的,再去调用本身,排列剩余的,也就是自己调用自己。

归纳法之前理解的是这样的:

1+3+5+……+(2n-3)+(2n-1) = (n-1)^2 + (2n-1) = (n^2 – 2n+1) +(2n-1) = n^2

先假设对n-1成立,然后加上n试一下,若成立,则整个式子就成立。

归纳法我见得不是特别多,书上例举了一个棋盘问题,有兴趣的同学可以看下书。

归纳法和递归法还有许多其他的应用。这篇先到这里。

点赞