数据结构(python)

来源:互联网 发布:单片机原理图设计 编辑:程序博客网 时间:2024/06/13 23:56
  1. 数据结构学会更有思路,效率,节约开销
  2. 算法实现的语言并不重要,重要的是思想,算法是独立存在的一种解决问题的方法和思想

     常见时间复杂度

执行次数函数举例阶非正式术语12O(1)   常数阶2n+3O(n)   线性阶3n2+2n+1O(n2)  平方阶5log2n+20O(logn)  对数阶2n+3nlog2n+19O(nlogn)  nlogn阶6n3+2n2+3n+4O(n3)  立方阶2nO(2n)  指数阶


算法的五大特性

  1. 输入: 算法具有0个或多个输入
  2. 输出: 算法至少有1个或多个输出
  3. 有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
  4. 确定性:算法中的每一步都有确定的含义,不会出现二义性
  5. 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成

O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)   【最坏情况】


      数据存储影响速度,效率          +=与= +效率不同(少用加号)
数据结构指数据对象中数据元素之间的关系
总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体

  

线性表

1、顺序表:list和tuple

2、单向链表:










  1. 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是不像顺序表一样连续存储数据,而是在每一个节点(数据存储单元)里存放下一个节点的位置信息(即地址)。
  2. 栈(stack),有些地方称为堆栈,是一种容器,可存入数据元素、访问元素、删除元素,它的特点在于只能允许在容器的一端(称为栈顶端指标,英语:top)进行加入数据(英语:push)和输出数据(英语:pop)的运算
  3. 双端队列(deque,全名double-ended queue),是一种具有队列和栈的性质的数据结构。

算法(好难):

  1. 冒泡排序  --前后依次换

    def bubble_sort(alist):     for j in range(len(alist)-1,0,-1):        # j表示每次遍历需要比较的次数,是逐渐减小的        for i in range(j):            if alist[i] > alist[i+1]:                alist[i], alist[i+1] = alist[i+1], alist[i]li = [54,26,93,17,77,31,44,55,20]bubble_sort(li)print(li)


  2. 选择排序(体操排队,假设一个,选择大或者小)

首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。

def selection_sort(alist):    n = len(alist)    # 需要进行n-1次选择操作    for i in range(n-1):        # 记录最小位置        min_index = i        # 从i+1位置到末尾选择出最小数据(找出索引)        for j in range(i+1, n):            if alist[j] < alist[min_index]:                min_index = j        # 如果选择出的数据不在正确位置,进行交换        if min_index != i:(数据交换)            alist[i], alist[min_index] = alist[min_index], alist[i]alist = [54,226,93,17,77,31,44,55,20]selection_sort(alist)print(alist)

3插入排序(从大往小依次比较)


def insert_sort(alist):    # 从第二个位置,即下标为1的元素开始向前插入    for i in range(1, len(alist)):        # 从第i个元素开始向前比较,如果小于前一个元素,交换位置        for j in range(i, 0, -1):            if alist[j] < alist[j-1]:                alist[j], alist[j-1] = alist[j-1], alist[j]alist = [54,26,93,17,77,31,44,55,20]insert_sort(alist)print(alist)

4快速排序

步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

def quick_sort(alist, start, end):    """快速排序"""    # 递归的退出条件    if start >= end:        return    # 设定起始元素为要寻找位置的基准元素    mid = alist[start]    # low为序列左边的由左向右移动的游标    low = start    # high为序列右边的由右向左移动的游标    high = end    while low < high:        # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动        while low < high and alist[high] >= mid:            high -= 1        # 将high指向的元素放到low的位置上        alist[low] = alist[high]        # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动        while low < high and alist[low] < mid:            low += 1        # 将low指向的元素放到high的位置上        alist[high] = alist[low]    # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置    # 将基准元素放到该位置    alist[low] = mid    # 对基准元素左边的子序列进行快速排序    quick_sort(alist, start, low-1)    # 对基准元素右边的子序列进行快速排序    quick_sort(alist, low+1, end)alist = [54,26,93,17,77,31,44,55,20]quick_sort(alist,0,len(alist)-1)print(alist)

5希尔排序--拆,排,合,拆,排

:将数组列在一个表中并对列分别进行插入排序,重复这过程,不过每次用更长的列(步长更长了,列数更少了)来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身还是使用数组进行排序。
 
def shell_sort(alist):    n = len(alist)    # 初始步长    gap = n / 2    while gap > 0:        # 按步长进行插入排序        for i in range(gap, n):            j = i            # 插入排序            while j>=gap and alist[j-gap] > alist[j]:                alist[j-gap], alist[j] = alist[j], alist[j-gap]                j -= gap        # 得到新的步长        gap = gap / 2alist = [54,26,93,17,77,31,44,55,20]shell_sort(alist)print(alist)

分治法的精髓:
分--将问题分解为规模更小的子问题;
治--将这些规模更小的子问题逐个击破;
合--将已解决的子问题合并,最终得出“母”问题的解;

6归并排序归并排序的思想就是先递归分解数组,再合并数组

def merge_sort(alist):    if len(alist) <= 1:        return alist    # 二分分解    num = len(alist)/2    left = merge_sort(alist[:num])    right = merge_sort(alist[num:])    # 合并    return merge(left,right)def merge(left, right):    '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组'''    #left与right的下标指针    l, r = 0, 0    result = []    while l<len(left) and r<len(right):        if left[l] < right[r]:            result.append(left[l])            l += 1        else:            result.append(right[r])            r += 1    result += left[l:]    result += right[r:]    return resultalist = [54,26,93,17,77,31,44,55,20]sorted_alist = mergeSort(alist)print(sorted_alist)



搜索的几种常见方法:顺序查找、二分法查找(有序表)、二叉树查找、哈希查找


二叉树(二维空间)

顺序存储(少) 链式存储

常见的一些树的应用场景

1.xml,html等,那么编写这些东西的解析器的时候,不可避免用到树
2.路由协议就是使用了树的算法
3.mysql数据库索引
4.文件系统的目录结构
5.所以很多经典的AI算法其实都是树搜索,此外机器学习中的decision tree也是树结构


二叉树的遍历







原创粉丝点击