3. 数组和列表

先说基本的线性结构,经常使用的就是线性结构,也是比较简单的,特色以下:html

内存连续,一开始就会分配一块固定的内存给它,能够经过下标去快速访问经常使用的数组和列表。python


在python 里面有array和list两种git

Array:github

python中array用到的机会没有list多,数组

先演示一下array的用法(https://docs.python.org/2/library/array.html):数据结构

from array import array

arr = array('u', 'abcdefg')
print (arr[0])
print (arr[3])
print (arr[5])

结果:app

aide

dspa

f3d

缺点也比较明显:

(1)只能存同一种类型,不想list能够在不一样下标存不一样类型的元素;

(2)只能存一些比较基本的数值、字符类型,用得不是不少,通常用numpy里面的array,来作一些数值的处理。


List:

list也是一个线性结构

(1)list的工做过程

经过C解释器代码能够看到是按照 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ....的顺序增加的

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

image.png


append:


操做 内存分配策略 平均时间复杂度
init[] *  pylistobj O(1)
append(0)

image.png
append(0)会分配4个pylistobj,不会一次只分配一个,会占用空间

当分配足够的空间,时间复杂度是O(1),不然它就会从新开辟并拷贝原来的数据到新开辟的空间中去,这时就会退化,时间复杂度是O(n)
append(1) image.png
append(2) image.png
append(3)

image.png

append(4)

image.png当超出它的大小限制的时候,会进行一个resize的操做,由于不够装了,因此从新分配8个空间

























insert:

insert

insert 通常会往中间插入,这样会比较耗费时间,会从新进行内存分配,好比insert一个元素 -1,这时就要从新开辟空间,总长度就变成了16

image.png
数组的容量称为capacity(总内存分配的容量),而length指的是有多少个元素,好比以前append了5个元素,insert一个-1,这时length就是6,即6个元素,而capacity是16,因此insert操做会从新的去分配,因此他的时间复杂度平均下来是O(n)

O(n)


pop:

pop

pop默认是移除最后一个元素,因此时间复杂度是O(1)

image.png
由于只是要把第5位指针往前面移动一位,这时length的长度变成5个,时间复杂度O(1);

但若是从中间进行pop的时候,这样就会把后面的元素往前移,这时候时间复杂度就会退化,变成O(n).

O(1)

O(n)


remove:

remove

image.png
加入要把中间的元素删除掉,要把后面的每个元素全都往前移,这时候的时间复杂度是O(n)

O(n)


如图:

操做 平均时间复杂度
list[index] O(1)
list.append O(1)
list.insert O(n)
list.pop(index), default last element O(1)
list.remove O(n)


因此在用list的时候,频繁的进行insert/remove的时候,或是在中间进行pop的话,

可能list就不是一个合适的数据结构,要选用其余更高效的数据结构。


练习:用list实现array的ADT

实现一个定长的数组array的ADT

ps:在其余一些语言中,内置的数组结构就是定长的。

class Array(object):
    def __init__(self, size=32):
        self._size = size
        self._items = [None] * size     #定义一个长度为size,元素是none的列表

    def __getitem__(self, index):
        return self._items[index]       #定义方法,能够经过[index]进行获取元素

    def __setitem__(self, index, value):
        self._items[index] = value

    def __len__(self):
        return self._size

    def clean(self, value=None):        #清空数组
        for i in range(len(self._items)):
            self._items[i] = value

    def __iter__(self):
        for item in self._items:
            yield item



#单测(pip install pytest)
def test_array():
    size = 10           #指定size长度
    a = Array()         #实例化
    a[0] = 1            #set方法
    assert a[0] == 1    #get方法

    a.clean()           #clean方法
    assert a[0] is None #clean方法


#pytest array_list.py

相关文章
相关标签/搜索