算法图解,整理

1.选择排序

找出其中最大/最小的数字,然后排到新的数组中,并展示出来。

def findsmallest(alist):
    smallest = alist[0]
    smallest_index = 0
    for i in range(1, len(alist)):
        if alist[i]<smallest:
            smallest = alist[i]
            smallest_index = i
    return smallest_index

def selection_sort(alist):
    new_alist = []
    for i in range(len(alist)):
        smallest = findsmallest(alist)
        new_alist.append(alist.pop(smallest))
    return new_alist

2.插入排序

典型的递归方式

def insert_sort(alist, n):
    if n==0: return
    insert_sort(alist, n-1)
    j=n
    while j>0 and alist[j-1]>alist[j]:
        alist[j-1], alist[j] = alist[j], alist[j-1]
        j-=1
    return alist

3.递归的方式

3.1编写sum的代码

def sum(alist):
    if len(alist) == 0: return
    return alist[0] + sum(alist[1:])

3.2计算列表包含元素数

def count(alist):
    if alist == []: return
    return 1 + count(alist[1:])

3.3查找最大值

def max(alist):
    if len(alist) == 2:
        return alist[0] if alist[0]>alist[1] else alist[1]
    sub_max = max(alist[1:])
    return alist[0] if alist[0]>sub_max else sub_max

3.4快速排序

def quick_sort(alist):
    if len(alist)<2:
        return alist
    else:
        pivot = alist[0]
        less = [i for i in alist[1:] if i<=pivot]
        great = [i for i in alist[1:] if i>pivot]
        return quick_sort(less) + pivot + quick_sort(great)

3.5归并排序

def merge(left, right):
    alist = []
    i = j =0
    while i<len(left) and j<len(right):
        if left[i]<right[j]:
            alist.append(left[i])
            i+=1
        else:
            alist.append(right[j])
            j+=1
    alist+=left[i:]
    alist+=right[j:]
    return alist

def merge_sort(alist):
    if len(alist)<=1: return alist
    middle = len(alist)//2
    a = merge_sort(alist[:middle])
    b = merge_sort(alist[middle:])
    return merge(a, b)

4.1迪克斯特拉算法

graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2
graph["a"] = {}
graph["a"]["fin"] = 1
graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["fin"] = 5
graph["fin"] = {}

infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["fin"] = infinity
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["fin"] = None

proceed = []
def find_lowest_cost_node(costs):
    lowest_cost = float("inf")
    lowest_cost_node = None
    for node in costs:
        cost = costs[node]
        if cost<lowest_cost and node not in proceed:
            lowest_cost = cost
            lowest_cost_node = node
    return lowest_cost_node

node =find_lowest_cost_node(costs)
while node is not None:
    cost = costs[node]
    neighbors = graph[node]
    for n in neighbors.keys():
        new_cost = cost + neighbors[n]
        if costs[n]>new_cost:
            costs[n] = new_cost
            parents[n] = node
    proceed.append(node)
    node = find_lowest_cost_node(costs)

4.2电台

stations = {}
stations["kone"] = set(["id", "nv", "ut"])
stations["ktwo"] = set(["wa", "id", "mt"])
stations["kthree"] = set(["or", "nv", "ca"])
stations["kfour"] = set(["nv", "ut"])
stations["kfive"] = set(["ca", "az"])

final_stations = set()
states_need = set(["mt", "wa", "or", "id", "nv", "ut"])
while states_need:
    best_station = None
    states_covered = set()
    for station, states in stations.items():
        covered = states&states_covered
        if len(covered)>len(states_covered):
            best_station = station
            states_covered = covered
states_need -= states_covered
final_stations.add(best_station)

5.1B树(B-tree)

B树和平衡二叉树稍有不同的是B树属于多叉树又名平衡多路查找树(查找路径不只两个),数据库索引技术里大量使用者B树和B+树的数据结构,让我们来看看他有什么特点;

1)排序方式:所有节点关键字是按递增次序排列,并遵循左小右大原则;

(2)子节点数:非叶节点的子节点数>1,且<=M ,且M>=2,空树除外(注:M阶代表一个树节点最多有多少个查找路径,M=M路,当M=2则是2叉树,M=3则是3叉);

(3)关键字数:枝节点的关键字数量大于等于ceil(m/2)-1个且小于等于M-1个(注:ceil()是个朝正无穷方向取整的函数 如ceil(1.1)结果为2);

(4)所有叶子节点均在同一层、叶子节点除了包含了关键字和关键字记录的指针外也有指向其子节点的指针只不过其指针地址都为null对应下图最后一层节点的空格子;

最后我们用一个图和一个实际的例子来理解B树(这里为了理解方便我就直接用实际字母的大小来排列C>B>A)

插入点流程:

定义一个5阶树(平衡5路查找树;),现在我们要把3、8、31、11、23、29、50、28 这些数字构建出一个5阶树出来;

遵循规则:

(1)节点拆分规则:当前是要组成一个5路查找树,那么此时m=5,关键字数必须<=5-1(这里关键字数>4就要进行节点拆分);

(2)排序规则:满足节点本身比左边节点大,比右边节点小的排序规则;

b树节点删除

(1)节点合并规则:当前是要组成一个5路查找树,那么此时m=5,关键字数必须大于等于ceil(5/2)(这里关键字数<2就要进行节点合并);

(2)满足节点本身比左边节点大,比右边节点小的排序规则;

(3)关键字数小于二时先从子节点取,子节点没有符合条件时就向向父节点取,取中间值往父节点放;

特点:

B树相对于平衡二叉树的不同是,每个节点包含的关键字增多了,特别是在B树应用到数据库中的时候,数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每个块的大小为4K,每次IO进行数据读取时,同一个磁盘块的数据可以一次性读取出来)把节点大小限制和充分使用在磁盘快大小范围;把树的节点关键字增多后树的层级比原来的二叉树少了,减少数据查找的次数和复杂度;

b+树

  • 概念

 

B+树是B树的一个升级版,相对于B树来说B+树更充分的利用了节点的空间,让查询速度更加稳定,其速度完全接近于二分法查找。为什么说B+树查找的效率要比B树更高、更稳定;我们先看看两者的区别

 

  • 规则

 

(1)B+跟B树不同B+树的非叶子节点不保存关键字记录的指针,只进行数据索引,这样使得B+树每个非叶子节点所能保存的关键字大大增加;

(2)B+树叶子节点保存了父节点的所有关键字记录的指针,所有数据地址必须要到叶子节点才能获取到。所以每次数据查询的次数都一样;

(3)B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针。

(4)非叶子节点的子节点数=关键字数(来源百度百科)(根据各种资料 这里有两种算法的实现方式,另一种为非叶节点的关键字数=子节点数-1(来源维基百科),虽然他们数据排列结构不一样,但其原理还是一样的Mysql 的B+树是用第一种方式实现);

1、B+树的层级更少:相较于B树B+每个非叶子节点存储的关键字数更多,树的层级更少所以查询数据更快;

2、B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同所以查询速度要比B树更稳定;

3、B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B树高。

4、B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B树一样需要对每一层进行遍历,这有利于数据库做全表扫描。

B树相对于B+树的优点是,如果经常访问的数据离根节点很近,而B树非叶子节点本身存有关键字其数据的地址,所以这种数据检索的时候会要比B+树快。


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值