静态数组与动态数组的主要区别是什么?
- A静态数组的下标访问更慢
- B动态数组可以通过移到更大的内存块来增长
- C动态数组把元素存储在链接的节点中,因此可以一次增长一个
- D静态数组只能存储数字
显示提示
- Python 的 list 和 Java 的 ArrayList 都是其中一种的例子。
- 两个错误答案已被划掉。剩下的两个中有一个是正确的。
显示答案和解析
为什么是这个答案
静态数组大小固定;动态数组在满时分配一个更大的数组并把元素复制过去。
免费的数据结构选择练习题,附提示和解析,分三个难度:关键术语与事实, 概念应用, 案例与分析。
最大堆性质是什么?
做得好。想再做下一题吗?准备好做下一题了吗? 每个主题每天都有 5 道新题。
学习本课之前: 算法与复杂度
数据结构是在内存中组织数据的一种方式,使某些操作很快:查找一个项目、添加一个、删除一个。
没有哪种结构在所有操作上都快。选择一种结构就是选择哪些操作应该开销小。它们的开销用大 O 表示,其中 n 为项目数。
两个基本的构件是数组和链表。
数组把项目存储在一整块内存里,一个接一个。计算机可以算出第 i 个项目在哪里,所以读取 a[i] 只需 O(1)。在前面插入意味着移动每一个项目:O(n)。
链表把每个项目存储在一个节点里,节点带有指向下一个节点的指针。最后一个指针为 null。在头部(h)插入只改变一个指针:O(1)。但要到达第 i 个项目,你必须沿着 i 个指针走:O(n)。
双向链表还带有指向前一个节点的指针,所以你可以双向行走。
答案: 读取下标 i 处的项目. 数组直接算出第 i 个项目的地址。链表必须从头部沿着 i 个指针走。在最前面插入则正好相反:对链表开销小,对数组开销大。
栈像一摞盘子:你只在顶部添加和移除。最后进入的项目最先出来:LIFO(后进先出)。
队列像收银台前的队伍:你在队尾加入,在队首离开。最先进入的项目最先出来:FIFO(先进先出)。
双端队列(deque)允许在两端添加和移除。优先队列总是先移除优先级最高的项目;它通常用堆来实现。
答案: 栈. 撤销必须先撤销最近的操作:后进先出。队列会先撤销最早的操作。
树有一个最顶端的节点,即根。其他每个节点恰好有一个父节点。没有子节点的节点是叶子。有 n 个节点的树有 n − 1 条边。
在二叉树中,每个节点最多有两个子节点。二叉搜索树(BST)增加了一条规则:左子树中的键比该节点小,右子树中的键比它大。
在 BST 中查找沿着一条路径向下,所以开销是 O(高度)。平衡树(AVL、红黑树)使高度保持在 log₂ n 附近。按排序顺序插入键会形成高度为 n 的链。
堆是一种二叉树,其中每个父节点都比它的子节点小(最小堆)或大(最大堆)。最小值或最大值在根处,插入和移除的开销为 O(log n)。
哈希表存储键值对。哈希函数把键变成下标,所以插入和查找平均只需 O(1)。两个键得到同一个下标称为冲突,用链地址法(每个槽一个链表)或开放寻址法(尝试另一个槽)解决。
图有由边连接的顶点,边可以有方向或权重。它可以存为邻接矩阵(O(V²) 内存),或邻接表(O(V + E))。
答案: 20. 20 比 50 小,所以它向左到 30。它也比 30 小,所以再向左。40 比 30 大,成为它的右子节点。
题目常常描述一个任务,问哪种结构合适,或者问某些操作之后结构是什么样子。
跟着每一步走。打开下一步之前,先试着预测它。
键 50、30、70、20、40 和 60 按此顺序插入一棵空的二叉搜索树。中序遍历的结果是什么?查找 60 需要多少次比较?
第一个键 50 成为根。
30 比 50 小,所以放在左边。70 比 50 大,所以放在右边。
20:比 50 小,比 30 小,所以在 30 的左边。40:比 50 小,比 30 大,所以在 30 的右边。60:比 50 大,比 70 小,所以在 70 的左边。
中序遍历先访问左子树,然后是该节点,再是右子树。
这得到 20、30、40、50、60、70:键按排序顺序排列,BST 总是如此。
与 50 比较:更大,向右。与 70 比较:更小,向左。与 60 比较:找到了。
查找需要 3 次比较,每层一次。
中序:20, 30, 40, 50, 60, 70。查找 60 需要 3 次比较。
答案: 1. 队列是先进先出,所以 1 最先离开。3 是栈(pop)的答案,栈返回最新的项目。
对于从下标 0 开始存放在数组中的堆,下标 i 的子节点在 2i + 1 和 2i + 2,它的父节点在 ⌊(i − 1) / 2⌋。
静态数组与动态数组的主要区别是什么?
静态数组大小固定;动态数组在满时分配一个更大的数组并把元素复制过去。
在二叉最小堆中,extract-min 是如何工作的?
最后一个元素填补根上的空位,并与其较小的子节点交换,直到满足堆性质,耗时 O(log n)。
在没有按秩合并和路径压缩的情况下,含 n 个元素的并查集结构中一次 find 操作的最坏代价是多少?
朴素的合并可能把树连成一条长链,因此 find 可能要沿着 n − 1 个父指针走;这两种启发式方法使其接近常数。
没有哪种结构在所有操作上都快。选择一种结构就是选择哪些操作应该开销小。它们的开销用大 O 表示,其中 n 为项目数。
两个基本的构件是数组和链表。
每道题有四个选项,只有一个正确。 卡住了?先打开一个小提示,需要时再查看完整解析。