【数据结构】记录

数组与链表区别

数组和链表是两种常见的数据结构,它们有几个关键区别:

  1. 存储方式

    • 数组:在内存中连续存储一组相同类型的元素,这使得数组支持随机访问,即可以通过索引直接访问任何位置的元素。
    • 链表:由节点组成,每个节点包含数据和指向下一个节点的指针(单向链表)或同时包含指向前一个节点和下一个节点的指针(双向链表)。链表的节点可以在内存中是不连续的,这使得插入和删除操作更加高效,但是访问节点时需要按照顺序一个接一个地遍历。
  2. 插入和删除操作的效率

    • 数组:在数组中插入或删除元素时,需要移动后续元素来保持连续性,这可能需要 O(n) 的时间复杂度,其中 n 是数组的长度。
    • 链表:链表的插入和删除操作通常只涉及节点之间的指针调整,因此插入和删除操作的时间复杂度通常是 O(1),即常量时间。
  3. 随机访问的效率

    • 数组:由于数组的元素在内存中是连续存储的,因此可以通过索引在常量时间内进行随机访问。
    • 链表:由于链表的节点不一定是连续存储的,因此不能直接通过索引进行随机访问,必须按顺序遍历链表来访问特定位置的元素,这使得随机访问的效率较低。
  4. 空间复杂度

    • 数组:通常情况下,数组的空间分配是静态的,一旦创建后大小固定。如果需要更多的空间,可能需要重新分配内存并复制数据,这可能会导致额外的开销。
    • 链表:链表的空间分配是动态的,每个节点可以在运行时动态分配。这意味着链表可以灵活地扩展或收缩,只要内存可用。

综上所述,数组适合需要频繁随机访问元素的情况,而链表适合频繁插入和删除操作的场景。

前序遍历

中序遍历

二叉树

搜索二叉树(二叉查找树)

二叉查找树(BST:Binary Search Tree)是一种特殊的二叉树,它改善了二叉树节点查找的效率。二叉查找树有以下性质:

对于任意一个节点 n,

  • 其左子树(left subtree)下的每个后代节点(descendant node)的值都小于节点 n 的值;
  • 其右子树(right subtree)下的每个后代节点的值都大于节点 n 的值。

红黑树

树的遍历

四种主要的遍历思想为:

  • 前序遍历:根结点 —> 左子树 —> 右子树

  • 中序遍历:左子树—> 根结点 —> 右子树

  • 后序遍历:左子树 —> 右子树 —> 根结点

  • 层次遍历:只需按层次遍历即可

二分查找

https://mp.weixin.qq.com/s/0Ni9i78uRWjZj4hrhTH03g

二分思想

本质上是折半查找思想,每一轮查找的范围是上一轮的一半,每次查找比较中间元素的值和目标值的大小,比较结论决定取哪一半边作为下一轮的查找范围。当查找范围缩小到空时停止。

局限性:有序、数组

  • 有序性:保证每次取半的意义
  • 数组:数组寻址的复杂度是 O(1)
    如果是用链表存储的一串数,二分查找是无意义的。链表的寻址是 O(n)。

跳表

为什么需要跳表

  • 链表查询太慢 → O(n)
  • 什么算法查询快?二分!→ O(logn)
  • 怎么把二分思想在链表中实践?→ 跳表的诞生 → O(?)

二分查找

  • 有序
  • 数组元素可以随机访问 → 寻址 O(1)

改造链表

  • 有序,不在改造范围内
  • 加快寻址速度
    • 空间换时间 → 上索引
    • 构建索引层 → 每 2 个节点提取 1 个到上一级,逐层构建

时间复杂度

  • 跳表高度:n, n/2, n/4, n/8, …, n/(2^k) → log2n
  • 每层遍历 m 个节点 → O(m*logn)
  • 每层索引最多只需要遍历 3 个节点 → O(logn)
    空间复杂度
  • n/2 + n/4 + n/8 + … + 8 + 4 + 2 → n-2 → O(n)
  • 实际操作中,链表中存储的对象元素很大,索引节点只会存- - 关键信息(比如 id)和指针,索引占用的额外空间可以忽略不计

跳表 索引的更新实现(随机 + 概率)

随机建立索引
  • 原链表,随机抽 n/2 个元素建立一级索引
  • 一级索引,随机抽 n/4 个元素建立二级索引
  • 以此类推,元素越多,索引分布越均匀
概率(随机)更新索引
  • 设计一个特别的函数,按照概率返回 [1, MAX_LEVEL] 之间的整数
  • 1/2 的概率返回 1,不需要更新索引,直接在在原链表中插入元素
  • 1/4 的概率返回 2,需要为新元素建立一级索引
  • 以此类推,无论插入多少个元素,各级索引的节点数依然是 n/2, n/4, ….

Redis 源码

在这里插入图片描述

跳表相关问题

  • 是否了解跳表?

  • Redis 为什么用跳表?

  • Redis 为什么用跳表?为什么不用红黑树?

  • 实现跳表(变态!)

  • 二分思想在链表的应用,提升查找效率,O(n) → O(logn)

  • 空间换时间,构建索引层,空间复杂度 O(n)

  • 增删改查都很高效 -> O(logn)

加分点

  • 索引层的更新,看过 Redis 跳表的源码,一些侃侃而谈
  • 跳表和红黑树的对比
    • 跳表能按照指定的区间查数据
    • 红黑树实现起来很复杂,跳表实现起来不容易出错(不给自己挖坑)
    • 高效查找、动态插入删除,都能做到 O(logn)
    • 共同点
    • 区别

延伸点

  • 对比红黑树
  • 对比散列表
  • Redis 的其他特性,除了跳表,我还知道 xxxx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值