python数据结构之排序、查找算法

18 篇文章 0 订阅
12 篇文章 0 订阅

1.排序算法

"""
排序 - 冒泡排序、选择排序、归并排序、快速排序
冒泡排序 - O(n ** 2):两两比较,大的下沉
35, 97, 12, 68, 55, 73, 81, 40
35, 12, 68, 55, 73, 81, 40, [97]
12, 35, 55, 68, 73, 40, [81]
12, 35, 55, 68, 40, [73]
...
选择排序 - O(n ** 2):每次从剩下元素中选择最小
-----------------------------------------
归并排序 - O(n * log_2 n) - 高级排序算法
35, 97, 12, 68, 55, 73, 81, 40
[35, 97, 12, 68], [55, 73, 81, 40]
[35, 97], [12, 68], [55, 73], [81, 40]
[35], [97], [12], [68], [55], [73], [81], [40]
[35, 97], [12, 68], [55, 73], [40, 81]
[12, 35, 68, 97], [40, 55, 73, 81]
[12, 35, 40, 55, 68, 73, 81, 97]
-----------------------------------------
快速排序 - 以枢轴为界将列表中的元素划分为两个部分,左边都比枢轴小,右边都比枢轴大
35, 97, 12, 68, 55, 73, 81, 40
35, 12, [40], 68, 55, 73, 81, 97
[12], 35, [40], 68, 55, 73, 81, [97]
[12], 35, [40], 55, [68], 73, 81, [97]
[12], 35, [40], 55, [68], 73, [81], [97]
"""
def select_sort(origin_items,comp=lambda x,y:x<y):
    """简单选择排序"""
    items=origin_items[:]
    for i in range(len(items)-1):
        min_index=i
        for j in range(i+1,len(items)):
            if comp(items[j],items[min_index]):
                min_index=j
        items[i],items[min_index]=items[min_index],items[i]
    return items

def bubble_sort(origin_items,*,comp=lambda x,y:x>y):
    """冒泡排序"""
    items=origin_items[:]
    for i in range(1,len(items)):
        swapped=False
        for j in range(i-1,len(items)-1):
            if comp(items[j],items[j+1]):
                items[j],items[j+1]=items[j+1],items[j]
                swapped=True
        if swapped:
            swapped=False
            for j in range(len(items)-i-1,i-1,-1):
                if comp(items[j-1],items[j]):
                    items[j],items[j-1]=items[j-1],items[j]
                    swapped=True
        if not swapped:
            break
    return items

def merge_sort(items,comp=lambda x,y:x<=y):
    """归并排序"""
    if len(items)<2:
        return items[:]
    mid =len(items)//2
    left=merge_sort(items[:mid],comp)
    right=merge_sort(items[mid:],comp)
    return merge(left,right,comp)
def merge(items1,items2,comp=lambda x,y:x<=y):
    """合并(将两个有序列表合并成一个新的有序列表)"""
    items=[]
    index1,index2=0,0
    while index1<len(items1)and index2<len(items2):
        if comp(items1[index1],items2[index2]):
            items.append(items1[index1])
            index1 +=1
        else:
            items.append(items2[index2])
            index2+=1
    items +=items1[index1:]
    items +=items2[index2:]
    return items

def quick_sort(origin_items,comp=lambda x,y:x<=y):
    """快速排序"""
    items=origin_items[:]
    _quick_sort(items,0,len(items)-1,comp)
    return items
def _quick_sort(items,start,end,comp):
    """递归调用划分和排序"""
    if start<end:
        pos=_partition(items,start,end,comp)
        _quick_sort(items,start,pos-1,comp)
        _quick_sort(items,pos+1,end,comp)
def _partition(items,start,end,comp):
    """划分"""
    pivot=items[end]
    i=start-1
    for j in range(start,end):
        if comp(items[j],pivot):
            i+=1
            items[i],items[j]=items[j],items[i]
    items[i+1],items[end]=items[end],items[i+1]
    return i+1


def main():
    items=[35, 97, 12, 68, 55, 73, 81, 40]
    print(bubble_sort(items))
    print(quick_sort(items))
    print(select_sort(items))
    print(merge_sort(items))
if __name__ == '__main__':
    main()

2.查找算法

"""
查找 - 顺序查找和二分查找
算法:解决问题的方法(步骤)
评价一个算法的好坏主要有两个指标:渐近时间复杂度和渐近空间复杂度,通常一个算法很难做到时间复杂度和空间复杂度都很低(因为时间和空间是不可调和的矛盾)
表示渐近时间复杂度通常使用大O标记
O(c):常量时间复杂度 - 哈希存储 / 布隆过滤器
O(log_2 n):对数时间复杂度 - 折半查找
O(n):线性时间复杂度 - 顺序查找
O(n * log_2 n):- 对数线性时间复杂度 - 高级排序算法(归并排序、快速排序)
O(n ** 2):平方时间复杂度 - 简单排序算法(冒泡排序、选择排序、插入排序)
O(n ** 3):立方时间复杂度 - Floyd算法 / 矩阵乘法运算
也称为多项式时间复杂度
O(2 ** n):几何级数时间复杂度 - 汉诺塔
O(3 ** n):几何级数时间复杂度
也称为指数时间复杂度
O(n!):阶乘时间复杂度 - 旅行经销商问题 - NP
"""
from math import log2, factorial
from matplotlib import pyplot

import numpy


def seq_search(items: list, elem) -> int:
    """顺序查找"""
    for index, item in enumerate(items):
        if elem == item:
            return index
    return -1


def bin_search(items, elem):
    """二分查找"""
    start, end = 0, len(items) - 1
    while start <= end:
        mid = (start + end) // 2
        if elem > items[mid]:
            start = mid + 1
        elif elem < items[mid]:
            end = mid - 1
        else:
            return mid
    return -1


def main():
    """主函数(程序入口)"""
    num = 6
    styles = ['r-.', 'g-*', 'b-o', 'y-x', 'c-^', 'm-+', 'k-d']
    legends = ['对数', '线性', '线性对数', '平方', '立方', '几何级数', '阶乘']
    x_data = [x for x in range(1, num + 1)]
    y_data1 = [log2(y) for y in range(1, num + 1)]
    y_data2 = [y for y in range(1, num + 1)]
    y_data3 = [y * log2(y) for y in range(1, num + 1)]
    y_data4 = [y ** 2 for y in range(1, num + 1)]
    y_data5 = [y ** 3 for y in range(1, num + 1)]
    y_data6 = [3 ** y for y in range(1, num + 1)]
    y_data7 = [factorial(y) for y in range(1, num + 1)]
    y_datas = [y_data1, y_data2, y_data3, y_data4, y_data5, y_data6, y_data7]
    for index, y_data in enumerate(y_datas):
        pyplot.plot(x_data, y_data, styles[index])
    pyplot.legend(legends)
    pyplot.xticks(numpy.arange(1, 7, step=1))
    pyplot.yticks(numpy.arange(0, 751, step=50))
    pyplot.show()


if __name__ == '__main__':
    main()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值