数据结构和算法

Posted lucky75

tags:

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

数据结构和算法

  • 非常的重要,是编程的灵魂

算法

一个计算过程,解决问题的方法

衡量算法的标准

1.使用时间模块

import time
start_time = time.time()
#... 代码体
end_time  =time.time()
print(end_time - start_time) ### 耗时时间

缺点:必须以硬件相同为前提

2.时间复杂度

  • 时间复杂度是衡量算法好坏的一个标准,主要是看程序大概运行的次数
  • O()来表示
  • 一般来说,时间复杂度高的算法比复杂度低的算法慢
  • 常见的时间复杂度(按效率排序)
    • O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)
    • mysql的索引之所以快,就是因为他是o(logn)
  • 不常见的时间复杂度(看看就好)
    • O(n!) O(2n) O(nn) …
  • 如何一眼判断时间复杂度?
    • 循环减半的过程-->O(logn)
    • 有几次循环就是n的几次方的复杂度

3.空间复杂度(了解)

  • 比较代码所占用的内存空间
  • 但因为现在的计算机内存空间并不珍贵,所以不被重视

常见的算法:

  • 冒泡
  • 选择
  • 插入
  • 快排
  • 希尔
  • 归并
  • 桶排序
    • 计数

冒泡排序:

  1. 依次比较列表每两个相邻的数,如果前面的比后面的大,那么交换这两个数
  2. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较

时间复杂度:

  • 平均时间复杂度:O(n^2^)
  • 最低时间复杂度:O(n)
Python代码
li = [7, 5, 4, 6, 3, 8, 2, 9, 1]

def bubble_sort(li):
    for i in range(len(li)-1, 0, -1):
        for j in range(i):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]

if __name__ == '__main__':
    bubble_sort(li)
    print(li)
优化:

如果冒泡排序中执行一趟而没有交换,则列表已经是有序状态,可以直接结束算法。

li = [7, 5, 4, 6, 3, 8, 2, 9, 1]


def bubble_sort(li):
    for i in range(len(li)-1, 0, -1):
        flag = True
        for j in range(i):
            if li[j] > li[j+1]:
                li[j], li[j+1] = li[j+1], li[j]
                flag = False
        if flag:
            return None

if __name__ == '__main__':
    bubble_sort(li)
    print(li)

选择排序

为每一个位置选择当前最小的元素

  1. 从第一个元素开始对全部元素进行选择,选出全部元素中最小的给该位置;
  2. 再对第二个位置进行选择,在剩余元素中选择最小的给该位置;
  3. 重复进行“最小元素”的选择,直至完成第(n-1)个位置的元素选择,则第n个位置就只剩唯一的最大元素;

时间复杂度:O(n^2^)

Python代码
li = [7, 5, 4, 6, 3, 8, 2, 9, 1]

def select_sort(li):
    for i in range(len(li)-1):
        min_loc = i
        for j in range(i+1, len(li)):
            if li[min_loc] > li[j]:
                li[min_loc], li[j] = li[j], li[min_loc]

if __name__ == '__main__':
    select_sort(li)
    print(li)

注意:

选择排序不是稳定的排序算法,它在计算过程中会破坏稳定性。

举例:

序列58539.我们知道第一遍选择第1个元素“5”会和元素“3”交换,那么原序列中的两个相同元素“5”之间的前后相对顺序就发生了改变。

插入排序

  1. 将列表分为有序区和无序区两个部分。最初有序区只有一个元素。
  2. 每次从无序区选择一个元素,插入到有序区的位置,直到无序区变空。

时间复杂度:O(n^2^)

Python代码
li = [7, 5, 4, 6, 3, 8, 2, 9, 1]

def insert_sort(li):
    for i in range(1, len(li)):
        tmp = li[i]
        j = i - 1
        while j >= 0 and li[j] > tmp:
            li[j+1] = li[j]
            j -= 1
        li[j+1] = tmp

if __name__ == '__main__':
    insert_sort(li)
    print(li)

快速排序

  • 好写的排序算法中最快的
  • 快的排序算法中最好写的
  1. 取一个元素p(第一个元素),使元素p归位;

    归位:列表被p分成两部分,左边都比p小,右边都比p大

  2. 递归完成排序

Python代码
li = [7, 5, 4, 6, 3, 8, 2, 9, 1]

def partition(data, left, right):
    tmp = data[left]
    while right > left:
        while left < right and tmp <= data[right]:
            right -= 1
        data[left] = data[right]
        while left < right and tmp > data[left]:
            left += 1
        data[right] = data[left]
    data[left] = tmp

    return left

def quick_sort(data, left, right):
    if left < right:
        mid = partition(data, left, right)
        quick_sort(data, left, mid-1)
        quick_sort(data, mid+1, right)

quick_sort(li, 0, len(li)-1)
print(li)
Python代码(分而治之)
分而治之思想:
  1. 将问题分解为若干简单的子问题
  2. 通过递归寻求各个子问题的的解
  3. 合并各个子问题的解,从而得到原始问题的解
li = [7, 5, 4, 6, 3, 8, 2, 9, 1]

def quick_sort(data):
    """快速排序"""
    if len(data) >= 2:  # 递归入口及出口
        mid = data[len(data) // 2]  # 选取基准值,也可以选取第一个或最后一个元素
        left, right = [], []  # 定义基准值左右两侧的列表
        data.remove(mid)  # 从原始数组中移除基准值
        for num in data:
            if num >= mid:
                right.append(num)
            else:
                left.append(num)
        return quick_sort(left) + [mid] + quick_sort(right)
    else:
        return data

print(quick_sort(li))

以上是关于数据结构和算法的主要内容,如果未能解决你的问题,请参考以下文章

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

可以解密加密数据的片段吗?

从搜索文档中查找最小片段的算法?

如何标记从卷积神经网络的分割算法生成的图像片段?

伪代码

C语言100个经典算法源码片段