说在前面
感觉数据结构是一个很难也很容易错的部分,我刷了很多牛客上面的题目,然后也学习了一些课内课外的理论,踩过一些坑,遇到了一些不错的题,希望能总结下来帮助到大家。
正文
1.已知一段文本有$1382$个字符,使用了$1382$个字节进行存储,这段文本全部是由$a$、$b$、$c$、$d$、$e$这$5$个字符组成,$a$出现了$354$次,$b$出现了$483$次,$c$出现了$227$次,$d$出现了$96$次,$e$出现了$232$次,对这$5$个字符使用哈夫曼(Huffman
)算法进行编码,则以下哪些说法正确()使用哈夫曼算法进行编码,$a$、$b$、$c$、$d$、$e$这$5$个字符对应的编码值可以有多套,但每个字符编码的位(bit
)数是确定的
错误点:这个编码值不一样的原因是可以把树的左右定义为$0$或者$1$都可以,所以可以有多套,但是每套的长度是一样的
2. 线索化的二叉树中:$ltag=0$,指向节点的左孩子,$ltag=1$,指向节点前驱节点,同理$rlag=0$指向右孩子,$rlag=1$指向后继节点。
3. 关于折半查找树:涉及折半查找的,一定要考虑除以二的时候向下还是向上取整能够到达目的点的$index$,必须要统一,折半查找树也是。
4. 注意图连通是有向图还是无向图,有向图连同至少需要$n$条边,无向图只需要$n-1$条。
5. 二次探测再散列是左右摇摆着走,$-1+1-4+4$这样走。
6. 注意回顾霍夫曼树的建树方法(每次找两个最小的)它的加权路径长度是$\sum edge\times eachweight$。
7.估算完全二叉树叶子节点个数:$\frac{n+1}{2}+1$
(1)链表删除尾部,要么搜索到尾部节点也是$O(N)$要么尾指针移动也是$O(N)$
(2)二叉树最坏情况退化成链表
(3)平衡树干什么都是$O(logN)$
8. 中序遍历二叉搜索树是升序序列
9. 从节点的角度判断空指针(每个节点除了根节点都必定有一个指针和它相连)。
10. 利用了随机访问的性质的,在顺序存储更换为链式存储,则算法的时间效率会降低。
如堆排序和希尔排序。
11. 希尔和插入是具有一样的性质的东西,所以一荣俱荣,都与初始排列有关系,归并排序($merge$是比较加填入的过程,如果完全有序,每次比较就一轮完成,其他的全部复制即可),但是不管怎样归并都是$O(NlogN)$这是因为无论好坏,时间复杂度merge都是$O(length)$。
12.快排$i$次会有$i$个以上的数字出现在最终的位置。
13. 首先按拼音串的字母序排序,如果拼音串相同,则按当前词所在的顺序排序,看到这种描述就是说明要是稳定排序,所以不稳定的就不能选。
14. 插入排序也是从有序序列从后往前比较,由于被插入序列有序,所以可以折半查找。
15. 回忆拓扑排序,加入一个没有入度的点,删掉这个点,再继续加入没有入度的点,图中再删除这个,以此类推。
16. 必须要有中序才能唯一确定一颗二叉树。17. 快(快速排序)些(希尔排序)选(选择排序)一堆(堆排序)朋友来聊天吧
18. 归并的趟数是$logN$,因为一共有每轮归并都是对于所有元素都有一个操作应该是N,所以最终乘起来就是$NlogN$
19. 规模较小的时候,考虑递归时间都有可能大于排序时间。
20.注意区分建初始堆和堆的插入。
21. 如果在一个排序算法的执行过程中,没有一对元素被比较过两次或以上,则称该排序算法为节俭排序算法,以下算法中是节俭排序算法的有________。
A. 插入排序
B. 选择排序
C. 堆排序
D. 归并排序
这个题比较有意思,对于插入排序来说,每次插入只是和有序序列里面的数字相比,也就是无序抽一个和有序内的比,每次如此,不会交叉。选择排序的思想是对当前第$i$个位置上的数,那么在后续数组中,选最小的与$i$对换。说明肯定比较过第二小和第三的数。那么在$i+1$位置上,上次第二小和第三小的数还需要比较一次选出最小的与$i+1$交换。那么至少比较了两次。选择排序会有一个拿在手里的数。举个例子初始序列:$6$、$9$、$2$、$8$。
第一轮排序之后是$2$、$9$、$6$、$8$。其中$6$跟$9$、$6$跟$2$、$2$跟$8$各比较了一次;
第二轮排序之后是$2$、$6$、$9$、$8$。其中$6$跟$9$、$6$跟$8$各比较了一次;
第三轮排序之后是$2$、$6$、$8$、$9$。其中$9$跟$8$比较了一次。
归并排序仍然是两个世界的人互相比较,比较一轮就更换阵营,仍然不会重复。
22. 原地堆排序就是把排好序的和堆最后一个数字交换。
23. 外部排序最常用的是多路归并排序。
24. 堆一定是二叉树,但不一定是平衡二叉树。
25. 注意回路和环路
26. 设二叉树的先序遍历序列和后序遍历序列正好相反,则该二叉树满足的条件是()。
A.空或只有一个结点
B.高度等于其结点数
C.任一结点无左孩子
D.任一结点无右孩子
只有左孩子和只有右孩子都可以,所以只有B是符合的。
27. 堆排的好处就是要知道前$x$个数字,不需要把全部序列排好。
28. 带头节点Head
的单链表为空的判定条件是head->next=NULL
。原题排版有问题。
29. 注意要区分好数组和矩阵的带指针的表示方式。
30. 关于两个有序链表合并的最好情况和最坏情况,不过就是merge
函数中比完最短的那个序列或者比完最长那个序列,所以我觉得直接从本质上考虑就好,这种算法的本质:就是两个表进行比较,其中一个表比较完之后,剩下的直接插入。因此最好的情况,不用想的太复杂,其实就只是短的那个表比较完了:$O(min(m,n))$。而最坏的情况,就只是长的那个表比较完了:$O(max(m,n))$而已。
31. 关于数组的位置偏移:①注意每个位置的字节数②注意行主还是列主③用[0][0]带到那个公式里看看成不成立。
32. 稀疏矩阵经过压缩之后必然会失去随机存取的功能。
33. 线索二叉树:“一个二叉树通过如下的方法“穿起来”:所有原本为空的右(孩子)指针改为指向该节点在中序序列中的后继,所有原本为空的左(孩子)指针改为指向该节点的中序序列的前驱。”
34. 栈的定义top可以有两种形式,一种是指向了本来的栈顶,一个是指向了下一个进栈的位置,这两种表示方式是不同的,进栈的时候的情况也是不同的。
35. 判断一个东西是不是线性的,就看它除了首尾以外是不是只有一个直接前驱和一个直接后继。
36. 蚂蚁问题,钢球认为是可以从对方身体中穿过去的,最短时间就是最近距离对应的那个,最长时间就是最远距离对应的那个。
37. 计算地址差的时候,也就是相当于把两个地址都算出来然后求差,那么相应的[0][0]认为地址就是1,所以到后面是要减1的,本质上就是减去第一个地址。
38. 要快速排序能维持$NlogN$,就是要表的左右尽量均衡。
39.哈希表不能反映数据之间的逻辑关系,只能反映数据和关键字之间的逻辑关系。
40. 要从$1000$个数据元素中选五个最小的,堆排序和选择排序相比来说,堆排序更快,选择排序其实就是$1000+9999+9998+9997+9996$。而堆排序建堆是$1000$,每次排序要$logN$,也就是每次几乎$10$左右,调整$4$次加上$1000$也没多少。
41. 注意理解 线性$\neq$顺序。
42. 为了减少递归深度,每次都先处理短的那个部分。
43. 时刻注意在有规则的情况下,霍夫曼树左边一定要小于右边。
44. 选择排序不是所说的那样真正的拿一个最大或者最小的塞在有序序列前头,而是找到有序序列前面的那个index
,并且与其交换。
45. 从两个方向搜索双链表,比从一个方向搜索双链表的方差要小,如果是有序的,则按照靠近结果的那一侧去搜索,如果无序,那么其实期望是一样的。
46. 用$2$个栈模拟实现一个队列,如果栈的容量分别是$O$和$P(O>P)$,那么模拟实现的队列最大容量是多少?$2P+1$,只能最多加$1$,如果再多就不能实现先进后出了。
47. 循环队列中$(rear-head+maxSize)\%maxSize$为实际元素的个数
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。