详解python中list的实现技术-分离式动态顺序表!

这是python-list的官方实现方式,但其中关于分离式动态顺序表的实现方式描述的不够细致,如果你有数据结构基础的话可以直接去看这篇博客,如果没有的话不妨先看看这篇!

什么事顺序表?

  • 将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
  • 但是上面的解释可能还不够明确,大家可以尝试这样理解:
  • 在程序中,经常需要将一组(通常是同为某个类型的)数据元素作为整体管理和使用,需要创建这种元素组,用变量记录它们,传进传出函数等。一组数据中包含的元素个数可能发生变化(可以增加或删除元素)。
  • 对于这种需求,最简单的解决方案便是将这样一组元素看成一个序列,用元素在序列里的位置和顺序,表示实际应用中的某种有意义的信息,或者表示数据之间的某种关系。
  • 这样的一组序列元素的组织形式,我们可以将其抽象为线性表。一个线性表是某类元素的一个集合,还记录着元素之间的一种顺序关系。线性表是最基本的数据结构之一,在实际程序中应用非常广泛,它还经常被用作更复杂的数据结构的实现基础。

根据线性表的实际存储方式,分为两种实现模型:
顺序表,将元素顺序地存放在一块连续的存储区里,元素间的顺序关系由它们的存储顺序自然表示。
链表,将元素存放在通过链接构造起来的一系列存储块中。

了解了顺序表的实现方式,接下来我们聊聊什么事分离式动态顺序表:
详解python中list的实现技术-分离式动态顺序表!_第1张图片

  • 首先看顺序表a,也就是左侧的顺序表,再看这张图之前,大家要了解两个概念,逻辑地址与物理地址。
  • 逻辑地址指的就是当你想使用你存储在内存中的元素时,你引用(也可以称为索引)他的一种方式,举个列子,大家经常使用的list[index],这里的index就是逻辑地址。
  • 物理地址当你想要把一个列表存储到计算机时,cpu会在内存中为你开辟一块连续的地址(这里的地址即物理地址),举个列子:
    a = [1,2,3] 这里我们创建一个a列表,里面存储了1,2,3三个元素,那么他们是如何存储在内存中的呢?
    详解python中list的实现技术-分离式动态顺序表!_第2张图片
    其实a指向的就是红色的那一块区域,那么有人会问了,为什么我的列表里只有1,2,3你却存储了三个元素呢?
    其实这种设计机制,是为了你使用的时候方便,在红色框内,红色的数字1,2,3是列表中要存储的元素,最上面的三个数据时列表的头信息,他们分别存储的是,elemcount(元素个数),max(最大元素),min(最小元素),之所以存储这些信息是为了不用每一次访问这个列表是都要遍历一遍列表,节省了时间。
    而图最左侧的绿色框内,就是物理地址了。
    大家有没有想过为什么列表可以[index]索引呢?
    其实道理很简单,当你创建列表时,你会向内存申请一串连续的地址,那么当你得到第一个元素的物理地址时,你是不是就可以很轻松得把其余的元素都找到呢?
    很简单的一个寻址公式:Loc(ei) = Loc(e0) + c*i
    loc(ei)指的是你要寻找的元素的物理地址,loc(e0)指的是第一个元素的地址,c指的是列表中每个元素所占字节数,i指的就是元素在列表中的下标。

说完了物理地址,那我们来说说什么是分离式动态顺序表:
如果你在存储是总把元素与表头信息放在一起的话,会发生什么,却是你在使用时会很方便,索引很快寻找很方便,但是当你要扩大列表,甚至是改变其中元素类型呢,你不单单是想在列表中存储数据那么简单了,你想存字符串,甚至是对象的时候,那么这种存储方法显然会给你的计算机带来很大的负担,我们都知道,a = 1,a其实并没有指向1,a只是指向了1在内存中的物理地址,那么试想我们是不是也可以,让列表中的下标们也指向,元素们在内存中的物理地址呢?
详解python中list的实现技术-分离式动态顺序表!_第3张图片
这种存储方式就是所谓的元素外置了(也成为分离式),这种存储方式会大大,减少内存的负担。
说完了分离式再来说说什么是动态顺序表,其实这个动态很好理解,在讲物理地址的时候我说在列表的表头信息里,会存储当前列表的元素个数,那么当你在执行插入操作时,列表会自动的去给你扩容,即换一块更大的存储区域,这也就是所谓的动态了。

你可能感兴趣的:(python,数据结构和算法)