基础算法记录

Posted standby

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础算法记录相关的知识,希望对你有一定的参考价值。

 

二分查找

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

def binary_search(lst,item):
    low = 0
    high = len(lst)-1
    while low <= high:
        mid = (low + high)/2
        guess = lst[mid]
        if guess == item:
            return mid
        elif guess > item:
            high = mid - 1   # 注意索引的变更
        else:
            low = mid + 1    # 注意索引的变更
    return None


ret = binary_search(lst,17)
if ret:
    print(‘Index is {}‘.format(ret))
else:
    print(‘Not found.‘)

  

快速排序

# 基于 divide&conquer 的快速排序的Python实现
 
lst = [19, 4, 0, 7, 14, 8, 2, 12, 11, 17, 13, 3, 18, 10, 6, 1, 15, 5, 16, 9]
 
def quicksort(lst):
    if len(lst) < 2:
        return lst
    pivot = lst[0]
    left = [ ele for ele in lst[1:] if ele < pivot ]
    right = [ ele for ele in lst[1:] if ele >= pivot ]
    return quicksort(left) + [pivot,] + quicksort(right)
 
sorted_lst = quicksort(lst)
print(lst)
print(sorted_lst)

 

堆排序

参考: https://www.cnblogs.com/chengxiao/p/6129630.html

堆的定义和基本性质

堆是具有以下性质的完全二叉树:
    每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;
    或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆。

任意节点(索引为K)的父节点的索引是 (K-1)/2 。
任意节点(索引为K)的左叶子节点的索引是 2*K+1 ,右叶子节点的索引是 2*K+2 。
假设节点数为 N,那么最后一个非叶子节点的索引是 N/2-1 。

堆排序的基本思想

将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。

将其与末尾元素进行交换,此时末尾就为最大值。

然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。

如此反复执行,便能得到一个有序序列了。

堆排序代码实现

class HeapSort(object):
    def __init__(self, lst):
        self._list = lst

    def adjust(self, parent_idx, length):
        parent_val = self._list[parent_idx]
        child_idx = parent_idx*2+1
        while child_idx < length:
            # 比较左叶子节点和右叶子节点的大小, 取较大的一个
            if child_idx+1<length and self._list[child_idx]<self._list[child_idx+1]:
                child_idx += 1
            # 比较叶子节点和父节点的大小, 把较大值赋给父节点
            if self._list[child_idx] > parent_val:
                self._list[parent_idx] = self._list[child_idx] # 因为可能还需要进行下一层的替换, 所以这里替换操作只做一半
                parent_idx = child_idx
                child_idx = child_idx*2+1
            else:
                break
        self._list[parent_idx] = parent_val # 把当前循环的父节点的值放到最终位置

    def heap_build(self):
        # Step1: 构建大顶堆
        # 从最后一个非叶子节点开始调整, 从下至上 从右直左
        length = len(self._list)
        parent_idx = length//2-1
        while parent_idx >= 0:
            self.adjust(parent_idx, length)
            parent_idx -= 1
    
    def head_sort(self):
        # Step2: 堆排序
        length = len(self._list)
        for sub_length in range(length-1,-1,-1):
            # Step2.1: 交换堆顶元素与末尾元素
            tmp = self._list[0]
            self._list[0] = self._list[sub_length]
            self._list[sub_length] = tmp
            # Step2.2: 把最大值沉到列表末端, 重新调整堆结构
            # 注意: 这次调整堆结构是从堆顶开始的, 并且需要重排的列表也是随着最大值的下沉而逐渐减少, 即保证前一次得到的最大值不会参与到本次的堆调整
            self.adjust(0, sub_length)


lst = [19, 4, 0, 7, 14, 8, 2, 12, 11, 17, 13, 3, 18, 10, 6, 1, 15, 5, 16, 9]
obj = HeapSort(lst)
obj.heap_build()
obj.head_sort()

  

 

以上是关于基础算法记录的主要内容,如果未能解决你的问题,请参考以下文章

常用编程思想与算法

视频二次裁剪时间计算出原片的时间片段算法

视频二次裁剪时间计算出原片的时间片段算法

CSP核心代码片段记录

以下代码片段的算法复杂度

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]