2017-2018 20172309 《程序设计与数据结构(下)》第七章学习总结

2017-2018 20172309 《程序设计与数据结构(下)》第七章学习总结

一、教材学习内容总结

1.1关于二叉查找树的一些概念

  • 二叉查找树具有附加属性,其左孩子小于父节点、而父节点又小余或者等于右结点。
  • 因此二叉查找树的最右侧会存放最大元素、而其最左侧会存放最小元素。
  • 二叉查找树是二叉树的扩展,它绝大数方法都会用到递归,二叉查找树的平均查找深度为O(log2N).

    1.2实现二叉查找树

  • 添加元素(addElement操作)
    • 插入方法首先在插入的时候判断被插入元素的类型是不是Comparable类if (!(element instanceof Comparable)),如果不是则会抛出NoComparableException
      1. 如果根结点为null,被插入元素成为根结点。
      1. 根结点不为null,将使用comparaTo()方法与TargetElement进行比较,
      1. 得到的结果为-1、1时,分别放在父节点的左子树、和右子树。
      1. 然后继续跟接下来的结点进行比较,即重复步骤a、b、c。
    • 就像这样:
  • 删除操作(removeElement操作)
    • 删除操作将在二叉查找树中删除给定的Comparable元素,如果找不到、将抛出ElemenNotFoundException.
    • 查找到要删除的元素之后删除操作分为三种情况:
      • 没有左右子节点,可以直接删除这个结点。比如删除结点20.
      • 存在左节点或者右节点,删除该节点后其父结点与子节点连接。比如删除结点70。
      • 同时存在左右子节点,将用其右子树中最小的结点与之交换。比如删除结点30.
      1. 当我们将上面的二叉查找树使用中序遍历遍历时,得到的结果为上面的链表。
      2. 当我们删除结点30的时候,链表中32之后的所有结点都将往前移动一个位置,而且结点32是结点30之后的结点中最小的一个,因此它将成为代替被删除的那个结点。即:
      3. 结点替换后,原来的结点32将被删除。
  • removeAllOccurrencesremoveMinremoveMaxfindMaxfindMin方法都在:LinkedBinarySearchTree类

    1.3用有序列表实现二叉树

  • 树的作用之一是为其他集合提供高效的实现。
  • 树的使用实现集合会让有些操作变得高效,也会让一些操作变得低效:
操作 LinkList BinarySearchTreeList
removeFirst O(1) O(n)
removeLast O(n) O(n)
remove O(n) O(n)
first O(1) O(n)
last O(n) O(n)
contains O(n) O(n)
isEmpty O(1) O(1)
size O(1) O(1)
add O(n) O(n)

黑色加粗代表使用树后操作将变得低效。

红色字体代表该操作可能使树变得不平衡。

1.4AVL树

  • 二叉查找树的平衡很重要!不平衡时,当我们插入一个已经排好序的一组数字时,它会变成一个类似于链表的结构。如图:

    如果查找二叉树不平衡,其效率可能比线性结构还要低!因为每个结点还有额外的开销。
  • 要解决这个问题,我们有如下规定: 任何结点不得过深,即:任何结点的平衡因子的绝对值不能超过1;(平衡因子:左子树的高度减去右子树的高度)
    • 几个例子如下图:
  • AVL树的插入操作首先会按照普通搜索二叉树的插入操作进行,当插入一个数据后,我们会沿着插入数据时所经过的的节点回溯,回溯的过程中会判回溯路径中的每个节点的左子支高度与右子支高度之差的绝对值是否超过1,如果超过1我们就进行调整,调整的目的是使得该节点满足AVL树平衡的定义。调整的情况可以分为以下四旋转操作。
    • 左旋:以某一个节点为轴,它的右子枝逆针旋转,作为新子树的根,我们称之为左旋。

      • 节点X右子支比左子支高度大2,且插入的节点位于节点X右孩子节点XR的右子支上。
    • 右旋:以某一个节点为轴,它的左子枝顺时针旋转,作为新子树的根,我们称之为右旋。
      • 节点X左子支比右子支高度大2,且插入的节点位于X的左孩子节点XL的左子支上。
    • 左右旋:先经过一次左旋,然后经过一次右旋。
      • 节点X左子支比右子支高度大2,且插入的节点位于节点X左孩子节点XL的右子支上。
    • 右左旋:先经过一次右旋,再经过一次左旋。
      • 节点X左子支比右子支高度大2,且插入的节点位于节点X左孩子节点XL的右子支上
  • AVL树的实现:BinaryAVLTree
  • 关于红黑树
    • 见下面教材中的问题。

二、教材学习中的问题和解决过程

  • 问题1:如何理解红黑树?它的功能AVL树也能实现,要这玩意儿干嘛?
  • 问题1解决方案:
    • 认识红黑树:(书中的什么概念就不说了,就说说自己的理解吧。)红黑树的特点是需要进行复杂的颜色变化、以及在AVL树中的旋转,但是它的出现解决了AVL树维护慢、空间开销大的不足。
    • 现在我们来总结红黑树与AVL树的区别吧!
      1. AVL树又称为平衡二叉搜索树,他是一棵空树或者两子树的高度差绝对值不超过1.而红黑树用颜色标识高度,不是严格平衡的!
      2. 虽然AVL树的效率很高,但红黑树的效率更高。(例如:当进行删除操作而引起树不平衡时,AVL树最坏情况下需要维护从该节点到根结点所有节点的平衡,因而旋转的量级为(log2 N);而红黑树对于任何不平衡最多只需要旋转三次!)。
      3. 红黑树的查询性稍微逊色于AVL树,因为它比AVL树会稍微不平衡多一层,也就是说他会比AVL树多进行一次比较。

        结论来自这!

    • 总而言之,他虽然复杂,但是它的效率总的来说比AVL树高。

代码调试中的问题和解决过程

  • 问题1:在网上看代码时,发现了个问题:comparator中的comparable方法与平时用的comparaTo方法的异同点?
  • 问题1解决方案:
    • comparator这个东西是在网上看别人代码时看到的,他是作为一个比较器,我当时的疑问是为啥要这个东西,用ComparaTO这个方法不就好了么?如图:

      在之后的实验中我没有写这个构造器,准备使用ComparaTO方法,然后发现:

      调用不了ComparaTO方法,是因为只能这样用String1.comparaTO(String2)...,也就是只能比较String类型。要想比较其他类型,就得写一个比较器,其中用Compara(T value1,T value2)方法。
  • 问题2:如何实现左旋和右旋?
  • 问题2解决方案:
    • 额,这个东西书好像是看懂了,但是敲起代码来并没有那么容易,然后到网上找了找,根据是由有parent(是否是双指针)分为两种。
    • 第一种:有parent:

      这种方法,每一次当父节点指向新的子节点时,子节点也要指向父节点。
    • 第二种:没有parent:

      这种没有parent指针的方法,虽然看起来简单,但当它不能调用叔叔结点!有parent指针的可以,比如:
  • 问题三:在二叉查找树中添加元素时,当添加已有元素或者添加两个相同元素时会发生什么情况?当添加比它小的元素时,这个小的元素会出现在这两个相同元素的左边?(比如添加了两个相同的元素5后,在添加一个元素3,那么这个3在哪个5的左边?)
  • 问题3解决方案:
    对于添加已有结点或相同结点可以分类讨论:

    • 一:当添加已有结点时,后来的数据之间覆盖原来的数据,有可能人说这个没有用,在我看来,当一个节点有两个数据时,这就变得非常有用,比如这两个数据是:name、price。

      已有的数据为:name:牛奶 、price:2元
      后来的数据为:name:牛奶 、 price:2.5 元
      一般来说、在实际生活中的应用一个节点会有很多数据,所以一般不会全部相同的。因此更新尤为重要。

    • 二:在书中代码上,数据不会更新的。相同的元素会放在原元素的右结点上,当放上比他小的元素时,会存在于它的第一个出现的结点的左节点上。

代码托管

(statistics.sh脚本的运行结果截图)

上周考试错题总结

  • 本周错题暂没出答案!

点评模板:

博客或代码中值得学习的或问题:

- 队友对于自己不懂得问题懂得深究,比如同学、百度。
- 队友的事比我多、学习java的效率比我高。
- 队友很细心、能够发现一些小问题。

点评过的同学博客和代码

其他(感悟、思考等,可选)

在上一章中,我说那一章很难。现在想是我错了!这个十一章是难的我脑壳都疼!特别是那个AVL、红黑树,哎。我得看代码去了····

学习进度条(上学期截止7200)

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 260/0 1/1 05/05
第二周 300/560 1/2 13/18
第三周 212/772 1/4 21/39
第四周 330/1112 2/7 21/60
第五周 1321/2433 1/8 30/90
第六周 1024/3457 1/9 20/110
第七周 1024/3457 1/9 20/110

参考资料

原文地址:https://www.cnblogs.com/dky-wzw/p/9898475.html

时间: 2024-10-01 08:01:06

2017-2018 20172309 《程序设计与数据结构(下)》第七章学习总结的相关文章

20172328《程序设计与数据结构》第七周学习总结

学号20172328<程序设计与数据结构>第七周学习总结 第九章教材学习内容总结 1.继承的概念: 继承是在父类和子类之间建立一种"是"的关系. 用于派生新类的原始类称为父类.超类或基类,被派生出的类就称为子类或者亚类. 2.继承具有单向性.java中用extends来表示新类由现有类派生. 3.protected修饰符:当变量声明为protected可见性时,子类就可以引用它,并且使父类保持了一定的封装性. (在UML图中,用#表示protected可见性.) 4.sup

20172313 2017-2018-2 《程序设计与数据结构》第七周学习总结

20172313 2017-2018-2 <程序设计与数据结构>第七周学习总结 教材学习内容总结 学习了如何去创建一个子类. 学习了使用protected修饰符让子类能够访问一个父类公共变量和使用保留字super来调用父类的构造方法. 学习了如何对父类的方法进行重写. 初步学习了类层次结构,了解了Object类和抽象类以及接口的层次结构. 学习了子类怎样通过一个其他方法来引用父类中的方法和变量以及常量. 初步学习了类间继承关系的设计. 教材学习中的问题和解决过程 问题1:在学习接口的时候就有这

20172324 2017-2018-2 《程序设计与数据结构》第七周学习总结

20172324 2017-2018-2 <程序设计与数据结构>第七周学习总结 教材学习内容总结 编写类是定义一组类似的对象:类建立了对象的特征和行为,但没有位声明的变量预留内存空间(除非所声明的变量是静态的) 继承是从现有类派生新类的过程,并且是一种强有力的软件开发技术. super可用来访问构造方法.父类的构造方法不能直接按名字调用,但可用super引用调用父类的构造方法. 当子类和父类有相同的方法名时,子类方法将重写父类方法,子类方法优先.但是子类不能重写final方法. 子类不可以重写

20172313 2018-2019-1 《程序设计与数据结构》第七周学习总结

20172313 2018-2019-1 <程序设计与数据结构>第七周学习总结 教材学习内容总结 概述 二叉查找树:二叉查找树是一种含有附加属性的二叉树,即其左孩子小于父结点,而父结点又小于或等于右孩子.二叉查找树的定义是二叉树定义的扩展. 二叉查找树的各种操作 操作 说明 addElement 往树中添加一个元素 removeElement 从树中删除一个元素 removeAllOccurrences 从树中删除所指定元素的任何存在 removeMin 删除树中的最小元素 removeMax

20172333 2018-2019-1 《程序设计与数据结构》第七周学习总结

20172333 2018-2019-1 <程序设计与数据结构>第七周学习总结 教材学习内容总结 <Java软件结构与数据结构>第十一章-二叉查找树 一.二叉查找树的概念及相关方法 ①思路:二叉查找树与普通的二叉树的区别类似于有序链表与无序链表的差别,二叉查找树因为实现了Comparable接口的类型的对象,所以该二叉树在添加数据到树中的时候就会自动排序,将大于根节点的数据放在右结点,反之则保存在左结点.这样排序好的二叉树方便查找所以叫二叉查找树. ②方法: public inte

20172314 2017-2018-2 《程序设计与数据结构》第七周学习总结

20172314 2017-2018-2 <程序设计与数据结构>第七周学习总结 教材学习内容总结 创建子类: 继承就是从现有类派生新类的过程,通过在子类的声明头中写public class 子类名 extends 父类名;来实现. 特别注意: 子类的实例化并不依赖于父类的实例化. 继承具有单向性,父类不能引用子类中声明的变量和方法. 构造方法不会继承. protected修饰符: 父类中的公共方法可以在子类中通过名称访问,若子类想访问其私有方法,那么父类的方法就必须声明为protected可见

20172322 《程序设计与数据结构》第七周学习总结

20172322 2017-2018-2 <程序设计与数据结构>第七周学习总结 教材学习内容总结 学会了使用UML图来表示各类间关系,UML也可以使得编程的思路变得清晰.例如#代表可继承,+代表public,-代表private. 学会了使用super引用父类的构造方法,因为父类的构造方法不会继承给子类,但如果子类需要继承父类的构造方法需要使用super. 了解到当子类和父类有相同的方法名和签名时,子类方发将重写父类方法,例如书上例9.7.9.8,它的存在允许两个有继承关系的对象按照同名规则使

20172327 2018-2019-1 《程序设计与数据结构》第七周学习总结

20172327 2018-2019-1 <程序设计与数据结构>第七周学习总结 教材学习内容总结 第十一章 二叉查找树 概述 1.二叉查找树是一种带有附加属性的二叉树,即对树的每个结点都有左结点小于父结点,右结点小于或等于父结点. 2.二叉查找树的定义是二叉树定义的扩展. 3. | 方法 | 描述 | | -------- | :------------------------------------------: | | addElement | 往树中添加一个元素 | | removeEl

20172315 2018-2019-2 《程序设计与数据结构》第七周学习总结

20172315 2018-2019-2 <程序设计与数据结构>第七周学习总结 教材学习内容总结 二又查找树是一种含有附加属性的二又树,即其左孩子小于父结点,而父结点又小于或等于右孩子. 每个BinaryTreeNode对象要维护一个指向结点所存储元素的引用,另外还要维护指向结点的每个孩子的引用. 从二又查找树中删除一个元素时,必须推选出另一个结点来代替要被删除的那个结点. 二又查找树的最右侧结点会存放最大元素,而其最左侧结点会存放最小元素. 如果二又查找树不平衡,其效率可能比线性结构的还要低

20172311《程序设计与数据结构》第七周学习总结

20172311<程序设计与数据结构>第七周学习总结 教材学习内容总结 第十一章 二叉查找树 树是一种非线性结构,其中的元素被组织成一个层次结构 含有m个元素的平衡n元树具有的高度为lognm 树的数组实现之计算策略: 如果我们存储的树不是完全的或者只是相对完全的,则该数组会为不包含数据的树位置分配空间 树的数组实现之模拟链接策略: 这种方式使得元素能够连续存储在数组中,因此不会浪费空间,但是该方式增加了删除树中元素的成本. 树的遍历 1.先序遍历 即根节点在左右子树之前遍历: 先访问根节点