• python数据结构与算法-02_数组和列表


    线性结构

    本节我们从最简单和常用的线性结构开始,并结合 Python 语言本身内置的数据结构和其底层实现方式来讲解。
    虽然本质上数据结构的思想是语言无关的,但是了解 Python 的实现方式有助于你避免一些坑。

    我们会在代码中注释出操作的时间复杂度。

    数组 array

    数组是最常用到的一种线性结构,其实 python 内置了一个 array 模块,但是大部人甚至从来没用过它。
    Python 的 array 是内存连续、存储的都是同一数据类型的结构,而且只能存数值和字符。

    我建议你课下看下 array 的文档:https://docs.python.org/2/library/array.html

    你可能很少会使用到它(我推荐你用 numpy.array),我将在视频里简单介绍下它的使用和工作方式,最常用的还是接下来要说的 list,
    本章最后我们会用 list 来实现一个固定长度、并且支持所有 Python 数据类型的数组 Array.

    列表 list

    如果你学过 C++,list 其实和 C++ STL(标准模板库)中的 vector 很类似,它可能是你的 Python 学习中使用最频繁的数据结构之一。
    这里我们不再去自己实现 list,因为这是个 Python 提供的非常基础的数据类型,我会在视频中讲解它的工作方式和内存分配策略,
    避免使用过程中碰到一些坑。当然如果你有毅力或者兴趣的了解底层是如何实现的,可以看看 cpython 解释器的具体实现。

    操作平均时间复杂度
    list[index]O(1)
    list.appendO(1)
    list.insertO(n)
    list.pop(index), default last elementO(1)
    list.removeO(n)

    在这里插入图片描述

    用 list 实现 Array ADT

    讲完了 list 让我们来实现一个定长的数组 Array ADT,在其他一些语言中,内置的数组结构就是定长的。
    这里我们会使用 list 作为 Array 的一个成员(代理)。具体请参考视频讲解和代码示例,后边我们会使用到这个 Array 类。

    源码

    # -*- coding: utf-8 -*-
    
    # https://docs.python.org/2/library/array.html
    from array import array    # python 提供的比较原始的 array 类
    
    
    arr = array('u', 'asdf')
    
    print(arr[0], arr[1], arr[2], arr[3])
    
    
    # 实现定长的 Array ADT,省略了边界检查等
    
    class Array(object):
    
        def __init__(self, size=32):
            self._size = size
            self._items = [None] * size
    
        def __getitem__(self, index):
            return self._items[index]
    
        def __setitem__(self, index, value):
            self._items[index] = value
    
        def __len__(self):
            return self._size
    
        def clear(self, value=None):
            for i in range(len(self._items)):
                self._items[i] = value
    
        def __iter__(self):
            for item in self._items:
                yield item
    
    
    def test_array():
        size = 10
        a = Array(size)
        a[0] = 1
        assert a[0] == 1
        assert len(a) == 10
    
    # py.test array_and_list.py
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    小问题

    • 你知道线性结构的查找,删除,访问一个元素的平均时间复杂度吗?(后边我们会介绍这个概念,现在你可以简单地理解为一个操作需要的平均步骤)
    • list 内存重新分配的时候为什么要有冗余?不会浪费空间吗?
    • 当你频繁的pop list 的第一个元素的时候,会发生什么?如果需要频繁在两头增添元素,你知道更高效的数据结构吗?后边我们会讲到

    延伸阅读

    Python list implementation

    https://github.com/python/cpython/blob/master/Objects/listobject.c

    勘误

    视频里的 Array.clear 方法有误。应该是 for i in range(len(self._items)),已经在后续所有使用到 Array 的代码里修正

  • 相关阅读:
    uni-app:本地缓存的使用
    JavaScript 数据结构与算法1(数组与栈)
    U-Net生物医学图像分割讲解(Convolutional Networks for BiomedicalImage Segmentation)
    【Mongodb-01】Mongodb亿级数据性能测试和压测
    【图像处理笔记】SIFT算法原理与源码分析
    在三维项目前端开发中用THREEMesh创建网格对象设置几何体和材质
    IOT Core-设备接入网关
    大学生静态HTML网页源码——佛山旅游景点介绍网页代码 家乡旅游网页制作模板 web前端期末大作业
    Qt+OSG/osgEarth跨平台编译(用Qt Creator组装各个库,实现一套代码、一套框架,跨平台编译)
    抽象类和接口
  • 原文地址:https://blog.csdn.net/xiaoshun007/article/details/134393113