• 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 的代码里修正

  • 相关阅读:
    LevelDB 学习笔记2:合并
    Mock数据
    uni-app中tab选项卡的实现效果 @click=“clickTab(‘sell‘)“事件可传参数
    软考能评职称吗?怎么评?
    java开发的正常开发步骤和进度总结
    C# 开发的程序怎么默认以管理员身份运行
    擎创技术流 | ClickHouse实用工具—ckman教程(4)
    计算机保研-上岸华中科技大学(武汉光电国家研究中心)
    电影《万里归途》
    trivy【3】自定义扫描策略
  • 原文地址:https://blog.csdn.net/xiaoshun007/article/details/134393113