python 数据结构

1. 顺序表:
    max=9 num=5 [1,2,3,4,5, , , , ]
    优点:
        1. 元素存储紧凑,节省空间,除表元素外,只需要O(1)空间存储辅助信息max,num
        2. 查找速度快,通过下标进行快速定位
    缺点:
        1. 需要连续的存储区域,如果表很大就需要很大片的连续内存空间,如果很大的存储区只保存少量数据,会造成存储浪费
        2. 执行加入和删除时,会移动很多元素,效率低
        3. 创建表时需要考虑存储大小,而实际需求很难事先估计
    分离式存储:
        元素和辅助信息max,num分开存储,表空间不足时,把表复制到更大的空间实现扩展存储
        python为防止空间浪费,创建空表时分配8个元素的存储区域,如果表满就换一个4倍大的区域,如果表储存区域>=50000,则改变策略向系统申请
        2倍大的区域,引入后一种策略是为了防止空间浪费
    实现:
        开一块内存,依次存入,逻辑关系通过存储区的物理位置表示
    实例tuple:
        按元素个数分配内存,创建不变的顺序表,例如python中的tuple
        (1,2,3)
    实例list:
        创建表时预留一些空位,前面存放元素,后面留空位,便于扩展;前面存放存储区大小,和当前元素个数,随时更新

    尾端加入新元素append:
        根据num值添加元素,即可实现append
    中间添加insert:
        新元素放入后将原元素添加到尾部(非保序)
        新元素放入后原元素依次后移一位(保序)
    尾端删除元素:
        num减1即可, 索引不到即为删除
2. 单链表:
    掌握一个单链表,只要掌握这个表的首节点即可,从它出发,根据链接即可找到表里所有的数据元素
    [head 表头指针]->[1]->[2]->[3]->[4]->……->[表尾 None]
    优点:
        不必向系统申请整块内存空间,随意扩展,存储空间不连续
    缺点:
        存储密度小,每个节点都增加了一个链接域,增加的空间开销与节点数成正比O(n)
    创建空链表:
        申请一个内存区域,将表头变量设置为None,时间复杂度O(1)
    删除链表:
        在python中只需把表指针赋值为None,即可抛弃所有链表节点,解释器会自动回收不用的内存空间,时间复杂度O(1)
    判断是否为空链表:
        判断表头值是否为None,时间复杂度O(1)
    判断链表是否满:
        一般而言链表不会满,除非用完了所有可用的存储空间
    表头插入元素:
        申请新内存存入元素,改变表头索引到新内存head,新内存next索引到原头部,如下图,时间复杂度O(1)
        [head]->[10]->[1]->[2]
    其他位置插入元素:
        改变索引即可,时间复杂度O(n)
    删除表头元素:
        将表头指针指向第二个元素节点即可,废弃节点由python解释器回收,时间复杂度O(1)
    删除表尾元素:
        找到要删除元素的前一节点,改变next指向,时间复杂度O(n),因为即使增加了表尾引用域,也无法倒序找到前一元素的next,只能遍历整表
    删除其他位置元素:
        找到要删除元素的前一节点,改变next指向,时间复杂度O(n)
    扫描定位遍历:
        遍历整个表,时间复杂度O(n)
    单链表的高效列表反转算法:
        因为单链表的首端增删操作都是O(1),所以只需要不断的从原表首端取下节点,将其插入另一个表的首端,即可完成反转,时间复杂度O(n)
    单链表的简单变形:
        1. 求表的长度,遍历全表O(n)时间复杂度会成为效率问题,可以改变单链表的实现结构,增加一个表长度记录,这个记录不属于任何表
            元素,每次表的变动操作都需要维护计数值,求表长度时,直接返回该值,整体来看有得有失,O(1)时间内得到表长度,牺牲表操作时间
        2. 表对象增加尾部节点引用域,这样既可在O(1)时间内找到尾节点,表尾加入新元素的操作也可做到O(1),代价是表变动,值实时维护
        3. 循环单链表,把最后一个节点的next域不用None,而是指向表的第一个节点,这样就成了环,哪个节点算是表头或表尾主要是概念问题
3. 双链表:
    1. 在单链表的基础上增加另一方向的链接,也就是一个元素需要两个链接域,增加灵活性,牺牲空间,这样就得到了双向链接表
    2. 也可以增加尾部引用,高效访问和操作表尾元素
    3. 将表首尾相连就得到了循环链表(圆)
    <-[head]<-->[1]<-->[2]<-->[3]<-->[4]<-->……<-->[None]->
    优点:
        1. 增加尾部引用后,两端高效操作,一般节点的操作也会更加方便,从双链表的任一节点出发,可以找到其前后相邻节点,时间复杂度O(1)
        2. 灵活修改表结构和数据排列方式,只需要修改节点之间的链接即可
        3. 不需要大存储块,方便安排和管理,python解释器负责
    缺点:
        存储密度小, 每个节点都增加了一个链接域, 增加的空间开销与节点数成正比O(n)
    双链表的元素删除:
        如果有尾节点引用,首尾两端元素的加入/删除时间复杂度都是O(1),直接改变元素前后链接即可
    改变元素顺序:
        修改节点链接关系,通过修改节点的链接顺序来改变表元素的顺序
    扫描定位遍历:
        可以从表头或表尾开始,遍历整个表, 时间复杂度O(n)
    循环链表的遍历:
        可以从表中任一元素开始,但是要注意结束条件
4. 链表的缺点:
    整体来看双链表的缺点是空间占用,优点是灵活性
    1. 定位需要挨个遍历,需要线性时间O(n),顺序表直接通过下标定位O(1)
    2. 增加尾部指针后,尾部访问为O(1),删除操作需要定位到节点的next,双链表可以高效操作首尾,但牺牲了空间
    3. 要找到当前元素的前一元素,需要遍历整表,双链表可解决这个问题,但牺牲了空间
    4. 双链表提高了操作灵活性,但需要两个链接域,使用二分法前后两端同步查找可提高一倍速度,如何抉择看时间和空间如何平衡



浅谈单链表与双链表的区别: 浅谈单链表与双链表的区别_kangxidagege的博客-优快云博客_单链表和双链表的区别
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值