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

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

教材学习内容总结

《Java软件结构与数据结构》第十一章-二叉查找树

一、二叉查找树的概念及相关方法

  • ①思路:二叉查找树与普通的二叉树的区别类似于有序链表与无序链表的差别,二叉查找树因为实现了Comparable接口的类型的对象,所以该二叉树在添加数据到树中的时候就会自动排序,将大于根节点的数据放在右结点,反之则保存在左结点。这样排序好的二叉树方便查找所以叫二叉查找树。
  • ②方法:
public interface BinarySearchTreeADT<T> extends BinaryTreeADT<T>
{
    /**
     * Adds the specified element to the proper location in this tree.
     *
     * @param element the element to be added to this tree
     */
    public void addElement(T element);

    /**
     * Removes and returns the specified element from this tree.
     *
     * @param targetElement the element to be removed from the tree
     * @return the element to be removed from the tree
     */
    public T removeElement(T targetElement);

    /**
     * Removes all occurences of the specified element from this tree.
     *
     * @param targetElement the element to be removed from the tree
     */
    public void removeAllOccurrences(T targetElement);

    /**
     * Removes and returns the smallest element from this tree.
     *
     * @return the smallest element from the tree.
     */
    public T removeMin();

    /**
     * Removes and returns the largest element from this tree.
     *
     * @return the largest element from the tree
     */
    public T removeMax();

    /**
     * Returns the smallest element in this tree without removing it.
     *
     * @return the smallest element in the tree
     */
    public T findMin();

    /**
     * Returns the largest element in this tree without removing it.
     *
     * @return the largest element in the tree
     */
    public T findMax();
}
操作 说明
addElement 从树中添加一个元素
removeElement 从树中删除一个元素
removeAllOccurrences 从树中删除所指定元素的人和存在
removeMin 删除树中最小元素
removeMax 删除树中最大元素
findMin 返回一个指向树中最小元素的索引
findMax 返回一个指向树中最大元素的索引

二、用链表实现二叉查找树

  • ①二叉查找树的方法实现

    • 书上实现了大部分的方法,只剩下findMax和findMin以及removeMax的方法尚未实现。
public T findMax() {

        if ( isEmpty() ) {
            throw new RuntimeException("树为空");
        }

        return findMax(root).element;
    }
public T findMin()
{

        if ( isEmpty() )
        {
            throw new RuntimeException("树为空");
        }

        return findMin(root).element;
    }
public E removeMax()
   {
        E ret = maximum();
        root = removeMax(root);
        return ret;
    }
private Node removeMax(Node node)
   {

        if(node.right == null)
        {
            Node leftNode = node.left;
            node.left = null;
            size --;
            return leftNode;
        }

        node.right = removeMax(node.right);
        return node;
    }
  • ②相关的方法的一些注意事项

    • 1.构造函数一共有两个,一个负责创建一个空的LinkedBinarySearchTree,一个负责创建一颗根节点为特定元素的LinkedBinarySearchTree。
    • 2.添加元素示意图
    • 3.删除方法的实现与之前的线性研究结构不同,这里的删除不能直接将制定结点的相关引用结点给删除而是要用另外一个结点来替代该结点的位置。一共三种情况
      • 如果被删除结点没有孩子,则replacement返回null
      • 如果被删除结点有一个孩子,则返回这个孩子
      • 如果被删除结点有两个孩子,则返回中序后继者(中序后继者指得是,使用中序遍历之后将目标元素删除后的下一位)删除方法示意图

三、用有序列表实现二叉查找树

  • ①方法
操作 说明
removefirst 删除列表的首元素
removelast 删除列表的尾元素
remove 删除列表中的一个特定元素
first 考察列表前端的那个元素
last 考察列表末端的那个元素
contains 判定列表是否含有一个特定的元素
is Empty 判定列表是否为空
size 判定列表中的元素数目
public class BinarySearchTreeList<T> extends LinkedBinarySearchTree<T>
                      implements ListADT<T>, OrderedListADT<T>, Iterable<T>
{
    /**
     * Creates an empty BinarySearchTreeList.
     */
    public BinarySearchTreeList()
    {
        super();
    }

    /**
     * Adds the given element to this list.
     *
     * @param element the element to be added to the list
     */
    public void add(T element)
    {
        addElement(element);
    }

    /**
     * Removes and returns the first element from this list.
     *
     * @return the first element in the list
     */
    public T removeFirst()
    {
        return removeMin();
    }

    /**
     * Removes and returns the last element from this list.
     *
     * @return the last element from the list
     */
    public T removeLast()
    {
        return removeMax();
    }

   /**
    * Removes and returns the specified element from this list.
    *
    * @param element the element being sought in the list
    * @return the element from the list that matches the target
    */
    public T remove(T element)
    {
        return removeElement(element);
    }

   /**
    * Returns a reference to the first element on this list.
    *
    * @return a reference to the first element in the list
    */
    public T first()
    {
        return findMin();
    }

   /**
    * Returns a reference to the last element on this list.
    *
    * @return a reference to the last element in the list
    */
    public T last()
    {
        return findMax();
    }

   /**
    * Returns an iterator for the list.
    *
    * @return an iterator over the elements in the list
    */
    public Iterator<T> iterator()
    {
        return iteratorInOrder();
    }
}

四、平衡二叉查找树

  • ①蜕化树

    • 数根为最小元素,此时的二叉树为蜕化树,蜕化树的效率比线性结构还要低。
  • ②右旋
    • 1.使根的左子结点变为新的根。
    • 2.原根节点变为新根的右节点。
    • 3.原根节点的左子结点的右子结点变为原根结点的新的左子结点。图右旋示意图
  • ③左旋
    • 1.使根的右子结点变为新的根。
    • 2.原根节点变为新根的右节点。
    • 3.原根节点的右子结点的左子结点变为原根结点的新的右子结点。图左旋示意图
  • ④右左旋(内部)
    • 1.先右旋后左旋。图右左旋示意图
  • ⑤左右旋(内部)
    • 1.先左旋后右旋。图左右旋示意图

五、实现二叉查找树AVL树

  • ①AVL树

    • AVL树相较于普通的二叉搜索树,自主要的就是做了平衡化处理,使得二叉树变的平衡,高度降低。
    • 平衡因子就是左右子树的高度差(用右子树的高度减去左子树的高度)。
    • 当平衡因子大于1或者小于-1则该结点为树根的子树需要平衡。
    • 一个平衡树的不平衡的方法只有两种:插入结点或者删除结点。
  • ②AVL树的右旋
    • 当某结点的平衡因子<-1时,则证明该结点的左孩子过长,在该结点的左孩子的平衡因子也是<-1则此时需要使用右旋。
  • ③AVL树的左旋
    • 当某结点的平衡因子>1时,则证明该结点的右孩子过长,在该结点的右孩子的平衡因子也是>1的时候,则此时需要使用左旋。
  • ④AVL树的左右旋
    • 当某结点的平衡因子<-1时,则证明该结点的左孩子过长,在该结点的左孩子的平衡因子却>1则此时需要使用右左旋。
  • ⑤AVL树的右左旋
    -- 当某结点的平衡因子>1时,则证明该结点的右孩子过长,在该结点的右孩子的平衡因子却<-1的时候,则此时需要右左旋。

    六、实现二叉查找树:红黑树

  • ①红黑树
    • 根节点为黑色
    • 红色结点的所有孩子都是黑色
    • 从数根到树叶的每条路径都包含同样数目的黑色结点。
  • ②红黑树的元素插入
    • 图红黑树元素插入及调整
  • ③红黑树的元素删除
    • 图红黑树元素删除及调整
    • 在进行删除之前需要找到该结点的后继结点来替代图红黑树替代

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

  • 问题1:书上解释蜕化树的效率比链表还要低下为什么?
  • 回答1:最后在书上找到与我相同的问题,这个问题是说每个结点都有相应的两个子节点树的存储空间,而很多方法都有对于null的检测过程,就会浪费很多时间,效率必然比链表还要低
  • 问题2:红黑树插入原理解释不清楚。
  • 回答2:插入一个元素到红黑树中,需要沿着插入点到根节点的路径上移动(遍历),在每一个经过的结点有三个操作:如果右子节点是红色的而左子节点也是红色的,进行右旋转。
    如果左子节点是红色的且它的左子节点也是红色的,进行右旋转
    如果左右子节点均为红色,进行颜色转换。本质上就是正常的二叉树插入,而将红黑进行转化,
  • 问题3:红黑树相对于AVL的优点在哪里?
  • 回答3:1.红黑树的平衡是局部平衡所以平衡时旋转次数要通常比AVL少。2.红黑树在插入失衡最多两次平衡,删除失衡最多三次平衡,效率更高。3.读取比AVL树慢,但是维护更加容易与稳定。

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

    问题1:在编写ppAVL的实现的时候,在关于左旋代码的实现过程中出现空指针问题图

解答1:在进行debug的时候,脑阔疼,实在是看不懂debug的流程,按照书上的意思画了个草图,一步一步对照,后来发现指针的位置由于自己的疏忽给错对象了。改正后图

代码托管

-图代码

上周考试错题总结

  • 有但是不知道错在哪里因为结果还没出来。

结对及互评

基于评分标准,我给李楠的博客打分:7分。得分情况如下:

正确使用Markdown语法(加1分)

模板中的要素齐全(加1分)

教材学习中的问题和解决过程, (加3分)

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

感想,体会真切的(加1分)

点评认真,能指出博客和代码中的问题的(加1分)

点评过的同学博客和代码

  • 本周结对学习情况

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

看不懂。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 0/0 1/1 10/10
第二周 0/0 1/2 10/20
第三周 1500/1500 1/3 10/30
第四周 2761/4261 2/5 25/55
第五周 814/5075 1/6 15/70
第六周 1091/6166 1/7 15/85
第七周 1118/7284 1/8 15/100

原文地址:https://www.cnblogs.com/yanyujun527/p/9892137.html

时间: 2024-11-08 08:06:38

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

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

20172333 2018-2019-1 <程序设计与数据结构>第九周学习总结 教材学习内容总结 <Java软件结构与数据结构>第十五章-图 一.无向图 ①无向图的定义 图是由结点与结点相连接构成的,与树类似.这些结点被常常称作顶点(vertice),这些顶点的连接叫做边(edge). 无向图(undirected graph)是一种边为无序结点对的图. 两个顶点之间有一条连通边的顶点,我们称作它们为领接的(adjacent).这两个顶点也叫作邻居(neighbor),自己是自己的

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

20172330 2018-2019-1 <程序设计与数据结构>第二周学习总结 教材学习内容总结 集合 1.集合是一种对象,类似于保存其他对象的存储库 集合中的元素通常是按照他们添加到集合的顺序,或者是按元素之间的某种内在联系来组织的. 2.抽象数据类型(ADT)是由数据和在该数据上所实施的具体操作构成的集合. 3.栈是一种线性集合,元素按后进先出(LIFO)的方法进行处理,有push,pop,peek,isempty,size等常用操作 4.栈是用于计算后缀表达式的理想数据结构 5.Java

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

20172305 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 本书的第一章简单的介绍了计算机和JAVA的历史,基础内容很多,代码的讲解还没用正式进入,本周一直在做敲代码的准备,简单敲了老师给的"Hello World!"以及书后的PP1.3.PP1.4等简单的小程序. 教材学习中的问题和解决过程 问题1:三种不同类型的错误,运行错误和逻辑错误的混淆 问题1解决方案:针对EX1.20的"希望做加法时却做里乘法"进行了网上

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

20172314 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 本书第一章为计算机系统概述,前面是一些计算机相关的基础知识,让我对计算机有了一个总体的认识,不再是一片空白了,对主存储器和CPU影响深刻,主存储器用于保存程序和数据,CPU执行程序指令.在接下来的Java编程语言与程序开发部分,开始看的时候有点迷茫,不是很理解,后来先按照作业中附带的流程完成一些代码托管之后,接触了完整的简单的程序之后,再回过头来看书,看到的一些陌生的名词在脑海中就有了实际的对应,

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

20172317 2017-2018-2 <程序设计与数据结构>第一周学习总结 教材学习内容总结 重新温习了一遍计算机的基础 总算了解了局域网广域网因特网万维网这些东西之间的区别了 通过URL的例子知道了网址各个部分的含义 对Java编程语言和程序开发有了一个粗浅的了解 教材学习中的问题和解决过程 问题:练习题SR1.13出现了答案与题目不相符的情况 问题解决方案:题中有个选项是"网卡",答案中没有,反而有个题目没有的选项"调制解调器"(俗称"

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

20172322 2017-2018-2 <程序设计与数据结构>第二周学习总结 教材学习内容总结 了解了print与println的区别 了解了字符串的拼接可以用+来完成 了解了转义字符的使用 学会了使用赋值 学会使用部分算术运算符 学会了使用Scanner来实现交互性 教材学习中的问题和解决过程 问题1:在最初接触赋值时对foalt和double的赋值范围不了解 问题1解决方案:使用万能的度娘后看到一个高赞答案后有了了解 问题2:在提前预习时看到2.7图形后敲入的代码无法执行 问题2解决方案

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

20172328李馨雨<程序设计与数据结构>第二周学习总结 又到周五,李馨雨同学要开始写博客了.让我们开始吧!(????) 教材学习内容总结 1.首先是String类定义的字符串,然后是print和println的区别.转义字符的学习.(让我印象深刻的\b[回车符]在字符串结尾不显示哈哈,及其更新的\t[换行符],还有在课堂上真正明白了什么是回车.) 2.了解变量.常量.赋值语句.变量:保存数据的内存单元.常量:坚定自己不会变的数据!除非你用java的反射(有点复杂,改权限.去修饰符等等.没实

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

20172327 2017-2018-2 <程序设计与数据结构>第二周学习总结 教材学习内容总结 字符串的拼接和转义序列的使用 变量的声明和使用 讨论语法及表达式的处理 定义数据转换类型和实现类型转换的机制 创建Scanner类 教材学习中的问题和解决问题 暂无 代码学习中的问题和解决过程 问题1:在提交过程中,突然遇到无法上传的情况 问题2解决方案:通过上网查找,输入git pull之后弹出一个编辑框,选择关闭之后,再次用git push就成功了. 问题2:在按照例题2.10打代码时,Jav

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

学号20172328<程序设计与数据结构>第九周学习总结 教材学习内容总结(异常和递归) 第11章:异常 1.[异常处理]: 一个异常:是一个定义非正式情况或错误的对象,由程序或者运行时环境抛出,可以根据需要捕获和处理. 错误:错误类似于异常,但是错误代表不可恢复的问题并且必须捕获处理. 2.[处理异常的三种方法]:①根本不处理异常②当异常发生时处理异常③在程序的某个位置集中处理异常. 3.[未捕获的异常]:如果程序中不处理异常,则程序将非正常的终止运行,并产生关于描述在何处发生什么异常的信息

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

学号 20172326 <程序设计与数据结构>第九周学习总结 教材学习内容总结 异常(exception):定义非正常情况下或错误的情况的对象,由程序或运行时环境抛出,可根据需要进行相应的捕获处理. 异常与错误的区别:错误代表不可恢复的问题并且必须捕获处理.而异常可以忽视,或者使用try语句处理,或调用更高级的方法. 可检测异常与不可检测异常:可检测异常必须由方法捕获,或者必须在可能抛出或传递异常方法的throws子句中列出来.在方法定义的声明头中追加一条throws子句.不可检测异常不需要使