算法快速入门-基于《算法图解》的算法入门教程(1)

简介: 笔记

前言


       算法是一组完成任务的指令。任何代码片段都可视为算法。本篇文章旨在快速搭建算法框架,为读者快速入门算法打下基础,故涉及算法知识但尽量不涉及复杂的语法知识。


一、二分查找

       假如你需要在一本100页的书中查找所需要的某一页(如30页吧),我们可以从头开始翻页,一页一页地查找直到找到想找的那一页。但你可能不会这么做,因为你知道30页在全书的中部靠前的位置,所以你多半是先取到书的一半(50页)左右的位置,再向前翻。

       那么,当我们登录一个网站(如CSDN),输入我们的用户名和密码时,CSDN数据库必须先得核实你是否注册过账号,于是它就在数据库中寻找你的用户名。假如你的用户名为TJUTCM,那么它可以从A打头的位置查找,但显然更明智的做法是从中间开始查找。

       这种算法,普遍地被我们使用,我们称其为二分查找。

       实例:如果我在1-100中选择一个数字让你来猜,你会怎么做呢?是从1一直顺序报数1,2,3,...这样到100?还是使用别的思路呢?显然,这里使用二分查找再合适不过了。


def binary_search(list,item):
#这里的list为所查找的数字所在的有序数组,而item则为所查找的数字
    low=0
    high=len(list-1)
#low和list用于跟踪要在其中查找的列表部分
#只要范围没有缩小到只包含一个元素,就检查中间的元素
while low<=high:
    mid=(low+high)/2
    guess=list[mid]
    if guess==item:       #找到了元素
        return mid
    if guess>item:        #猜的元素大了
        high=mid-1
    else:                 #猜的元素小了
        low=mid+1
    return None           #没有要查找的元素

一般而言,对于包含n个元素的列表,用二分查找最多需要log2n(以2为底,n的对数)步,而简单查找最多需要n步。但需注意的是:仅当列表是有序的时候,二分查找才有用。


二、选择排序

       假如你需要在教务系统查看本学期的课程所对应的学分排序,将查询到的课程按照学分从低到高排序,一种方法是遍历这个列表(课程和其对应的学分),找出学分占比最低的课程,并将该课程添加到一个新列表中;再次这样做,找出学分占比第二低的课程;继续这样做,你将得到一个有序列表。

       O(n)时间意味着查看列表中的每个元素一次,我们对课程列表进行简单查找时,意味着每个课程都要查看一次,如此一来单趟就花费了O(n)的时间,而对于这种时间为O(n)的操作,你需要执行n次。

       因此对于这种时间为O(n)的操作,你需要执行n次。而这种算法我们称其为选择排序。


#将数组元素按从小到大的顺序排列,先编写一个用于找到数组中最小元素的函数
def findSmallest(arr)
    smallest=arr[0]        #存储最小的值
    smallest_index         #存储最小元素的索引
    for i in range(1,len(arr)):
        if arr[i]<smallest:
            smallest=arr[i]
            smallest-index=i
    return smallest_index
#现在可以用这个函数来实现选择排序算法了
def selectionSort(arr):    #对数组进行排序
    newArr=[]
    for i in range(len(arr)):
        smallest=findSmallest(arr)    #找出数组中最小的元素,并将其假如到新数组中
        newArr.append(arr.pop(smallest))
return newArr


       随着排序的进行,我们发现:每次需要检查的元素数在逐渐减少,最后一次需要检查的元素只有一个。既然如此,运行时间怎么还是O(n^2)呢?


       我们发现:第一次需要检查n个元素,但随后检查的元素个数依次为n-1,n-2,...,2和1。平均每次检查的元素数为n/2,因此运行时间为O(n^2/2),大O表示法省略诸如1/2这样的系数,故算法的时间复杂度为O(n^2)。


三、快速排序

       如果老师要求统计班级学生的人数,而又不想自己一个个数人数。于是老师便想到了个好主意:指定两个班级负责人,一男一女,让着两人分别去统计男生和女生的人数。这两个同学也不想自己一个个数人数,于是再把男生和女生部分分别划分为不同的小组,再让小组长去统计小组的人数......


       如此一样,人数统计问题便被人为地划分、简化为小问题,这些小问题又可以接着划分为更小的问题,直到问题不可划分。这时再一步步回退就能得出大问题的解了。我们将这种算法称为快速排序算法。

#使用快速排序算法的工作原理:
#(1)找出简单的基线问题
#(2)确定如何缩小问题的规模,使其符合基线条件
#(基线条件:为空或只包含一个元素的数组是“有序的”,不需要再排序)
def quicksort(array):
    if len(array)<2:
        return array
    else:
        pivot=array[0] #选择基准值
        less=[i for i in array[1:] if i<=pivot]
#由所有小于等于基准值的元素组成的数组  
        greater=[i for i in array[1:] if i>pivot]
#由所有大于基准值的元素组成的数组        
        return quicksort(less)+[pivot]+quicksort(greater)
print quicksort([1,4,3,2])    #这里为随机给的数组元素


       快速排序算法将问题逐步分解,最终分解直至子问题达到基线条件(为空数组或只包含一个元素)。实现快速排序时,随机地选择用作基准值的元素,快速排序的平均运行时间为O(nlogn)。


未完待续......


相关文章
|
4月前
|
Dart 算法 JavaScript
C#数据结构与算法入门教程,值得收藏学习!
C#数据结构与算法入门教程,值得收藏学习!
|
6月前
|
机器学习/深度学习 存储 人工智能
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法(三)
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法
|
6月前
|
存储 人工智能 搜索推荐
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法(二)
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法
|
6月前
|
存储 人工智能 算法
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法(一)
【利用AI让知识体系化】3万多字让你&我快速入门数据结构与算法
|
11月前
|
Rust Dart 算法
支持C#的开源免费、新手友好的数据结构与算法入门教程 - Hello算法
支持C#的开源免费、新手友好的数据结构与算法入门教程 - Hello算法
108 1
|
存储 算法 芯片
快速入门数字芯片设计,UCSD ECE111(七)enum枚举类型&优化SHA256哈希算法(二)
快速入门数字芯片设计,UCSD ECE111(七)enum枚举类型&优化SHA256哈希算法(二)
74 0
|
算法 安全 芯片
快速入门数字芯片设计,UCSD ECE111(七)enum枚举类型&优化SHA256哈希算法(一)
快速入门数字芯片设计,UCSD ECE111(七)enum枚举类型&优化SHA256哈希算法
93 0
|
存储 算法 数据处理
快速入门数字芯片设计,UCSD ECE111(六)SHA256哈希算法的状态机实现(二)
快速入门数字芯片设计,UCSD ECE111(六)SHA256哈希算法的状态机实现(二)
96 0
|
算法 安全 区块链
快速入门数字芯片设计,UCSD ECE111(六)SHA256哈希算法的状态机实现(一)
快速入门数字芯片设计,UCSD ECE111(六)SHA256哈希算法的状态机实现
139 0