算法-数据结构入门(一)——《算法图解》

先简单说一下概念:

算法:就是解决问题的方法、步骤;

数据结构:数据之间的相互关系(逻辑结构)+数据的逻辑结构在计算机中的存储(物理结构)

简单说一下两种数据结构:

数组:内存连续的一种数据存储。就是申请一块内存,挨个存放数据,地址连续,通过索引(下标)获取存储的数据;

缺点是:1.内存需要连续,容易溢出或者浪费内存;2.删除、添加都需要繁琐的移动后面的元素,不过高级语言都有封装好的添加删除函数;

优点是:读取元素很快,通过索引一步就可以,时间复杂度O(1);(大O表示法文末介绍)

链表:连续数据的内存不一定连续,每一个数据都存储下个数据的地址(详细的暂不讨论)

缺点是:查找是需要遍历整个链表;

优点是:删除和插入简单,一步即可

 

下面说第一个简单的算法:

抛出问题:查找26在不在数组[1,2,4,5,21,26,78,100]中

思考:最简单的,我们首先可以想到遍历这个数组,拿数组的每一个元素和26比较,如果相等就说明26在这个数组,否则则不在;这样走一遍的话需要的时间是O(n),就是从数组的第一个元素比较到最后一个元素,共比较n次;代码如下:

arr = [1,2,4,5,21,26,78,100]

def simple_search(arr,num):
    # i markup search progress
    i = 0 
    for x in arr:
        if x == num:
            print num ,'in this list'
        else:
            i = i + 1
        if i == len(arr):
            print num ,'not in this list'

simple_search(arr,26)

 这只是几个数,如果我们数据太大,这样做的话就会费时很久,有没有快速一点的查找方法呢?以前聚会的时候可能玩过一个游戏:就是一个人想一个100以内的数,写在手机上,然后大家开始猜,猜一个数,写的人会告诉你大了还是小了,依次下去,直到最后只剩一个数,谁最后猜中了,就会被惩罚。这个时候如果你想快点结束游戏的话,你会怎么做呢,当然是对半猜,先猜50,然后25或者75,依次下去,很快就会猜出答案。这其实就是我们今天要说的简单的查找算法:折半查找(二分查找):

原理如上面的游戏,先拿到数组中间的数arr[len/2-1],然后和你要找的数对比,然后按照上面所说不断折半,直到low>=high结束查找。代码如下:

arr = [1,2,4,5,21,26,78,100]

def binary_search(arr,num):
    low = 0
    high = len(arr) - 1
    
    while low < high:
        mid = (low+high) / 2 #python automatic downward alignment
        tem = arr[mid]
        if num == tem:
            print num ,'in this list'
        elif num < tem:
            high = mid - 1;
        else:
            low = mid + 1
    print num ,'not in this list'
    
binary_search(arr,26)

那么折半查找的时间复杂度是多少呢,我们可以简单的理解为对折,一个长为n的数组,对折下去,直到找到,最坏的情况复杂度为log(n),就是要找的数是第一个或最后一个,最好的是O(1),就是第一次对折就找到了。一般没其他标示的话,大O标示的是最坏情况的时间复杂度。

任何算法都是有缺陷的,或者说限制,折半查找的缺陷很好看:

1.作用于数组

2.数组有序

二分查找还有很多有趣的用处,感兴趣的可以下去找着玩玩,本节只介绍基本的理解和实现。

 

大O表示法:

是一种表示算法执行速度的方法,形式是:O(n),n是操作数,即执行这个算法,一共需要多少步操作。上面说的简单查找(第一中方法)最坏情况是n步操作,所以是O(n),折半查找最坏需要logn步,是O(logn)

 

你可能感兴趣的:(算法-数据结构入门)