python算法概述

本文概述了Python算法的基本概念、重要性,并列举了常见的算法思想如分治法、贪心法等。介绍了时间复杂度的大O表示法,推荐了算法书籍,并对比了数组与链表的时间复杂度和适用场景。同时,文章还提到了线性表、栈和队列等数据结构及其应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 Python算法概述

1.1 算法概念

数据结构:数据的存储结构,对这些数据进行操作。
算法:运算方法,解决问题的方法和思想。

1.2 算法的意义与重要性

(1)让代码可行、高效、低占用资源
(2)明白代码底层逻辑,方便使用和阅读代码
(3)面试必考,高薪企业看中
算法的5个基本要素:
(1)输入:0个或多个输入
(2)输出:至少有1个或多个输出
(3)有穷尽:可以终止
(4)确定性:不会有歧义
(5)可行性:有效性,可执行的步骤,明确的落地执行的

1.3 算法举例

算法是针对问题出现的,有问题的地方就有算法。
算法思想(加粗为5大常用算法):
(1)分治法:划分任务,越来越简单
(2)贪心法:1,3,5,找9元钱
(3)穷举法:所有组合方案列出来,比如试密码。答案全,但耗费精力
(4)递归法:调用函数本身,递归到本身
(5)递推法:数列根据前几项规律,得到第n项的规律
(6)回溯法:走迷宫,如果不通回到上个路口找其他路径,解决不下去,回到 回溯点,找其他方案
(7)动态规划法:用于数学中,寻找最优解
(8)迭代法:旧值 推导出 新值
(9)分支界限法:大问题找出最优解,找出各分支的上界和下届,再综合得到整个的优解

1.4 算法书籍推荐

《啊哈!算法》:c语言
《算法图解》:Python,3-4小时可以看完
《数据结构与算法 Python语言实现》
刷题:
LeetCode、牛客网nowcoder

2 时间复杂度

我们将算法执行运算的操作数丢弃低阶项,再去掉所有的系数。
在它前门加一个O,就是大O表示法
O(n):其中n是操作数

3 算法分析法则

3.1 一般法则
(1)for循环:循环体为O(n),循环次数为m,则总的时间复杂度=O(nm)
(2)嵌套的for循环:各个循环次数分别是a,b,c,则总的时间复杂度=O(n
ab…)
(3)顺序语句:各个语句的运行时间求和即可(或者说取较大值)
(4)if/else语句:总的时间复杂度=其中复杂度对打路径
3.2 常见复杂度
li.append()
li.insert()

4 二分法查找O(logn)

二分法:在有序数组中查找某一特定元素的搜索算法
搜索过程从数组的中间元素开始:
如果中间元素是正好要找的元素,则搜索过程结束;
如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较;
如果在某一步骤数组为空,则代表找不到。

# 先决条件:有序数组
# 数据类型有范围:其他语言如java采用表达式start+(end-start)/2可以防止溢出
# start =mid +1和end=mid-1,防止死循环
# 数据量不可过大,防止内存溢出
# 时间复杂度:O(log n)
def binary_search(arr,key):
    start = 0
    end = len(arr)-1
    while start <= end:
        mid = (start+end) // 2
        if arr[mid] < key:
            start = mid +1
        elif arr[mid] > key:
            end = mid + 1
        else:
            return mid
    return -1

5 数组vs链表

5.1 定义区别
数组:必须连续,存取麻烦;直接访问。为了解决计算机定址问题出现
链表:不要求连续,但需要内存地址标记,查找麻烦;顺序访问。作为原始数据类型存在。
5.2 时间复杂度区别

操作链表数组
查找O(n)O(1)
在头部插入/删除O(1)O(n)
在尾部插入/删除O(n)O(1)
在中间插入/删除O(n)O(n)

区别总结:
(1)链表插入/删除时间复杂度:当插入/删除指针当前指向的节点时,时间复杂度是O(1);当插入/删除某个给定值的节点时,我们需要遍历链表,时间复杂度是O(n)
(2)链表插入/删除时间复杂度O(n):需要进行遍历引起的;
数组插入/删除时间复杂度O(n):数据的拷贝覆盖导致的;
5.3 原理区别
插入删除很少,查询非常多,不会out of memory,采用数组(局部性原理,后续访问在一级缓存中);
频繁插入、遍历,查询检索很少,采用链表(每次都是内存访问节点)。
5.4 注
数据结构:数据的组织和存储方式,决定数据结构;
实现进行封装:封装数据类型。

6 线性表

6.1 线性表(线性逻辑和顺序):
(1)顺序表:数组(连续内存空间、类型相同)、引用数组(地址存为数组,通过地址访问,解决不同类型数据的问题)、动态数组(list)
(2)链表:单链表、双链表
(3)栈:先进后出(LIFO)
(4)队列:先进先出(FIFO)
(5)等等
6.2 栈(stack)&队列
运算过程中保存数据的,遇到不能确定的数据,缓冲存储结构。
栈:或叫堆栈、堆叠。先进后出(LIFO)
队列:先进先出(FIFO)

7 Python常见算法

7.1 选择排序

# 选择排序:不断选择最小的元素进行排序
# 运行时间和输入无关;数据移动是最少的。
# 时间复杂度:O(n^2),空间复杂度O(1)
def selection_sort(li): # 不断选择无序序列中最小的元素,放在第1个,再将该元素置于有序序列的最后
    for i in range(len(li)):
        min_index = i
        for j in range(i+1, len(li)): # 找到值最小的元素index
            if li[min_index] > li[j]:
                min_index = j
        li[i], li[min_index] = li[min_index], li[i]  #交换第i个元素和最小值的元素

7.2 冒泡排序

# 冒泡排序
# 运行时间和输入无关;
# 时间复杂度:O(n^2)
def bubble_sort(li): #两两比较,大的向右移动
    for i in range(len(li)-1): # i表示第几趟,共n-1趟
        for j in range(len(li)-i-1): # j 表示每趟比较的次数,为n-1-i次
            if li[j] > li[j+1]: # 如果前者大于后者
                li[j], li[j+1] = li[j+1], li[j] # 交换两者数值(也就是小于等于时,数值不变)
# 优化:时间复杂度:O(n)
def bubble_sort_1(li):
    for i in range(len(li)-1): # i表示第几趟,共n-1趟
        exchange = False
        for j in range(len(li)-i-1): # j 表示每趟比较的次数,为n-1-i次
            if li[j] > li[j+1]: # 如果前者大于后者
                li[j], li[j+1] = li[j+1], li[j] # 交换两者数值(也就是小于等于时,数值不变)
                exchange = True
        if not exchange:
            return li

7.3 插入排序

# 插入排序
# 运行时间取决于输入元素的顺序,有序比乱序、逆序快的多
# 应用:1. 数组中每个元素距离它的最终位置都不远;2. 一个有序的大数组接一个小数组;
# 3. 数组中只有几个元素的位置不正确。
def insertion_sort(li): # 无序序列中拿一个元素,扫描有序序列并插入
    for i in range(1, len(li)):
        tmp = li[i] # 刚摸到的牌
        j = i -1
        while j >= 0 and li[j] > tmp:  # 当j存在且大于tmp时,互换位置,比较前一个j;直到j不存在 或者 小于tmp时退出循环
            li[j+1] = li[j]
            j -= 1
        li[j+1] =tmp # 退出while循环的时候,将tmp插入当前j的后面一个位置

# 希尔排序:插入排序的优化
# 将待排序列划分为若干组,每组进行插入排序。完成后进行最后一步普通的插入排序。
# 各个子数组都很短;排序之后子数组都是部分有序的
# 时间复杂度:pass

7.4 归并排序

# 归并排序
# 分解问题;解决问题;合并问题
# 自顶向下,自底向上
def merge_sort(li): # 拆序列至1个元素,合并排序为2个元素;再合并排序
    if len(li) <= 1:
        return li
    middle = len(li)//2
    left = merge_sort(li[:middle])
    right = merge_sort(li[middle:])
    return merge(left, right)

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

7.5 快速排序

# 快速排序
# 时间复杂度:O(nlog n),空间复杂度高
# 快速排序优化:
# 1.切换到插入排序(5-15个长度为小数组);2.三取样切分(三个元素挑中间的元素作为中轴元素);
# 3. 三向切分的快速排序
def quick_sort(li): # 找中轴元素(基准),小左大等右;再两侧分别找中轴元素,继续排序
    if len(li) < 2:
        return li
    else:
        base = li[0] #选取中轴元素
        left =[elem for elem in li[1:] if elem < base] #小的放左边
        right = [elem for elem in li[1:] if elem > base] #大的放右边
        return quick_sort(left) + [base] + quick_sort(right)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值