数据结构与算法总结--链表

链表定义

链表是一种线性表
链表的内存结构是不连续的
链表的每一块内存被称为节点(node),除了存储数据还要存储指针

链表的特点

  • 插入\删除效率高

时间复杂度O(1),需要已知要插入\删除位置之前的节点指针,插入\删除时,只需要操作相关指针
如果是删除节点中值等于某个给定值的节点,时间复杂度为O(n),需要遍历链表

  • 查找效率低

查找时间复杂度(O(n)),需要从头遍历链表

  • 内存消耗高

和数组相比,内存消耗高,需要额外存储指针

链表数组对比

  • 常用操作时间复杂度对比
插入删除查找
数组O(n)O(n)O(1)
链表O(1)O(1)O(n)
  • 优缺点对比

数组
优点:简单易用,使用连续的内存,可以借助缓存机制,提高效率
缺点:数组占用连续内存,当需要的内存空间比较大时,容易出现内存不足问题;大小固定,当数组存储空间不够时,需要进行扩容,此时需要拷贝原有数据到新内存地址,操作比较耗时
链表
优点:链表没有大小限制,天然支持动态扩容
缺点:占用内存高,需要额外存储指针;插入删除操作频繁,会导致频繁的内存申请和释放,容易产生内存碎片,导致频繁的gc(java 自动垃圾回收)

常用链表

  • 单链表

每个节点只包含一个指针
尾节点的后继指针为null

  • 循环链表

除尾节点指向首节点外,其它同单链表
适合存储有循环特点的数据,如约瑟夫环问题

  • 双向链表

节点除存储数据外,还存储两个指针,一个指向前驱节点,一个指向后继节点
尾节点的后继指针、首节点的前驱指针为null
双向链表使用更方便,所以实际使用更广泛

  • 双向循环链表

尾节点的后继指针指向首节点,首节点的前驱指针指向尾节点

轻松写出链表代码技巧总结

  • 理解指针\引用的含义

将某个变量(对象)赋值给指针(引用),实际上就是就是将这个变量(对象)的地址赋值给指针(引用)

  • 警惕指针丢失和内存泄漏
  • 利用“哨兵”简化实现难度

链表中的“哨兵”节点是解决边界问题的,不参与业务逻辑。
“哨兵”节点不存储数据,无论链表是否为空,head指针都会指向它,作为链表的头结点始终存在。这样,插入(删除)第一个节点和插入(删除)其他节点都可以统一为相同的代码实现逻辑。

  • 重点留意边界条件处理

如果链表为空,代码能否正常工作
如果链表只含有一个(或者两个)节点,代码能否正常工作
代码能否正确处理头结点\尾节点

  • 举例画图,辅助思考
  • 多写多练
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值