20172327 2018-2019-1 《程序设计与数据结构》第七周学习总结
教材学习内容总结
第十一章 二叉查找树
概述 |
1.二叉查找树是一种带有附加属性的二叉树,即对树的每个结点都有左结点小于父结点,右结点小于或等于父结点。
2.二叉查找树的定义是二叉树定义的扩展。
3.
| 方法 | 描述 |
| -------- | :------------------------------------------: |
| addElement | 往树中添加一个元素 |
| removeElement | 从树中删除一个元素 |
| removeAllOccurrences | 从树中删除所指定元素的任何存在 |
| removeMin | 删除树中最小的元素 |
| removeMax | 删除树中最大的元素 |
| findMin | 返回一个指向树中最小元素的引用 |
| findMax | 返回一个指向树中最小元素的引用 |
用链表实现二叉查找树 |
1.每个BinaryTreeNode对象要维护一个指向结点所储存元素的引用,另外还要维护指向结点的每个孩子的引用。
用有序列表实现二叉查找树 |
1.用BinarySearchTreeList类实现ListADT接口和OrderedListADT接口。
2.
| 操作 | 说明 |
| -------- | :------------------------------------------: |
| add | 向列表添加一个元素 |
| removeFirst | 删除列表的首元素 |
| removeLast | 删除列表的末元素 |
| remove | 删除列表中一个特定元素 |
| first | 考察列表前端那个元素 |
| last | 考察列表末端那个元素 |
| contains | 判定列表是否含有一个特定元素 |
| is Empty | 判定列表是否为空 |
| size | 判定列表中的元素数目 |
3.树的主要使用之一就是为其他集合提供高效的实现。
4.BinarySearchTreeList实现的分析:
| 操作 | 说明 | LinkedList | BinarySearchTreeList|
| -------- | :--------------------------:| :--------------: | :---------------------: |
| add | 向列表添加一个元素 | O(n) | O(log n)* |
| removeFirst | 删除列表的首元素 | O(1) | O(log n) |
| removeLast | 删除列表的末元素 | O(n) | O(log n) |
| remove | 删除列表中一个特定元素 | O(n) | O(log n)* |
| first | 考察列表前端那个元素 | O(1) | O(log n) |
| last | 考察列表末端那个元素 | O(n) | O(log n) |
| contains | 判定列表是否含有一个特定元素| O(n) | O(log n) |
| isEmpty | 判定列表是否为空 | O(1) | O(1) |
| size | 判定列表中的元素数目 | O(1) | O(1) |
*add操作和remove操作都可能导致树变得不平衡。
平衡二叉查找树 |
1.如果二叉查找树不平衡,其效率可能比线性结构还要低。
2.维护树的平衡有着多种算法,有些蛮力方法(中序遍历,把数组的中间元素作为树根,再构造出左平衡子树和右平衡子树。),有些方案更优美(AVL树和红黑树)。
3.右旋: 在最小平衡子树根节点平衡因子>=2且在根节点的左孩子的左孩子插入元素,进行右旋
- 使树根的左孩子元素成为新的根元素。
- 使原根元素成为这个新树根的右孩子元素。
- 使原树根的左孩子的右孩子,成为原树根的新的左孩子。
4.左旋: 在最小平衡子树根节点平衡因子>=-2且在根节点的右孩子的右孩子插入元素,进行左旋。
- 使树根的右孩子元素成为新的根元素。
- 使原根元素成为这个新树根的左孩子元素。
- 使原树根的右孩子的左孩子,成为原树根的新的右孩子。
5.右左旋:最小平衡子树根节点(80)的右孩子(100)的左孩子(90)的子节点(95)插入新元素,先绕根节点的右孩子节点(100)右旋,再围根节点(80)左旋
6.左右旋:在最小平衡子树根节点(80)的左孩子(50)的右孩子(70)的子节点插入新元素,先绕根节点的左孩子节点(50)右旋,再围根节点(80)左旋
实现二叉查找树:AVL树 |
1.右子树的高度减去左子树的高度称为该结点的平衡因子。
2.树(或树的任何子树)只有两种途径能变得不平衡:插入结点或删除结点。
3.因为需要上溯树,所以AVL树通常最好实现为每个结点都包含一个指向其父结点的引用。
4.AVL树的插入操作首先会按照普通搜索二叉树的插入操作进行,当插入一个数据后,我们会沿着插入数据时所经过的的节点回溯,回溯的过程中会判回溯路径中的每个节点的左子支高度与右子支高度之差的绝对值是否超过1,如果超过1我们就进行调整,调整的目的是使得该节点满足AVL树平衡的定义。
教材学习中的问题和解决过程
- 问题1:如何理解红黑树?
- 解决方案:红黑树和之前所讲的AVL树类似,都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。自从红黑树出来后,AVL树就被放到了博物馆里,据说是红黑树有更好的效率,更高的统计性能。不过在我了解了红黑树的实现原理后,并不相信这是真的,关于这一点我们会在后面进行讨论。
红黑树和AVL树的区别在于它使用颜色来标识结点的高度,它所追求的是局部平衡而不是AVL树中的非常严格的平衡。之前我们在讲解AVL树时,已经领教过AVL树的复杂,但AVL树的复杂比起红黑树来说简直是小巫见大巫。红黑树是真正的变态级数据结构。
代码调试中的问题和解决过程
- 问题1:在实现ArrayOrderedListTest测试时,我遇到了显示最后一个数字时,人家显示为null这个问题。
图片 - 解决分析,在我对前面ArrayList类检查时,发现我在显示last时,将rear-1不小心写成rear了,所以它所读取的是最后一个后边的,所以肯定为空。
代码托管
结对及互评
正确使用Markdown语法(加1分)
模板中的要素齐全(加1分)
教材学习中的问题和解决过程, (加3分)
代码调试中的问题和解决过程, 无问题
感想,体会真切的(加1分)
点评认真,能指出博客和代码中的问题的(加1分)
- 20172317
基于评分标准,我给以上博客打分:4分。得分情况如下: - 20172320
基于评分标准,我给以上博客打分:8分。得分情况如下:- 结对学习内容
- 教材第11章,运行教材上的代码
- 完成课后自测题,并参考答案学习
- 完成程序设计项目:至少完成PP11.3、PP11.8
- 结对学习内容
其他(感悟、思考等,可选)
这周学的有点麻烦,栈还行,就是链表有点糊涂。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 8/8 | |
第二周 | 1306/1306 | 1/2 | 20/28 | |
第三周 | 1291/2597 | 1/3 | 18/46 | |
第四周 | 4361/6958 | 2/3 | 20/66 | |
第五周 | 1755/8713 | 1/6 | 20/86 | |
第六周 | 3349/12062 | 1/7 | 20/106 |
- 计划学习时间:10小时
- 实际学习时间:8小时
- 改进情况:
(有空多看看现代软件工程 课件
软件工程师能力自我评价表)
参考资料
原文地址:https://www.cnblogs.com/mrf1209/p/9898651.html