慕课网liuyubobobo老师课程学习笔记---part5:二分搜索树

这篇博客是关于二分搜索树的学习笔记,详细介绍了树结构的基础知识,特别是二分搜索树的概念和特点。内容包括二分搜索树的递归实现代码,以及前序、中序、后序遍历的规律。此外,还提到了非递归遍历方法,如Morris Traversal,但强调递归实现是最简单的方式。
摘要由CSDN通过智能技术生成

1、树结构的介绍
  见视频1解析。
在这里插入图片描述

2、二分搜索树的基础
  二叉树的介绍如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  二分搜索树的介绍
在这里插入图片描述
在这里插入图片描述

  注意,我们二分搜索树存储的元素必须具有可比较性,为了是存储的元素对象具有可比较性,元素类必须实现Comparable<E>接口,并复写接口的 compareTo(Object obj)方法以实现比较性。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
关于前序、中序、后序遍历的总结如下,注意理解他们为什么是哪个样子的!

1、前序:先处理本结点(这里是打印本结点),然后处理以左孩子结点为根的左子树所有结点,处理以右孩子结点为根的右子树所有结点。  在左/右子树里面,同样先处理本子树的根结点,再处理下一级左子树所有结点,再处理下一级的右子树所有结点。

2、中序:先处理本结点的左子树所有结点,再处理本结点,再处理本结点右子树所有结点。对于左子树或者右子树,同样是先处理下一级左子树所有结点,再处理当前根结点,再处理下一级右子树所有结点.
    中序遍历的结果就是当前二分搜索树所有元素排序后的结果!!!
    
3、总结:先处理本结点的左子树所有结点,再处理本结点右子树所有结点,最后处理本结点。 对于左子树或者右子树,同样是先处理下一级左子树所有结点,再处理下一级右子树所有结点,最后处理当前根结点。

  想要快速找出二分搜索树前序、中序、后序排列的结果,不需要像视频8那样苦苦寻找,我们遵循以下规律即可:

前序:对于所有的结点,处理顺序是:当前结点——左孩子结点——右孩子结点,直到左右孩子结点为null,则直接结束递归,返回上一级的递归;
中序:对于所有的结点,处理顺序是:左孩子结点——当前结点——右孩子结点,直到左右孩子结点为null,则直接结束递归,返回上一级的递归;
后序:对于所有的结点,处理顺序是:左孩子结点——右孩子结点——当前结点,直到左右孩子结点为null,则直接结束递归,返回上一级的递归;
需要注意的是,这些是对于所有结点适用!!!必须一直寻找左右孩子结点处理,直到当前结点为叶子结点,就不需要再考虑其左右孩子结点(都为null),就可以直接返回叶子结点!

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  二分搜索树的递归实现代码如下:(注意对比递归方法的宏观语意以及微观上是如何实现的。)

package com.lkj;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

//注意!泛型参数必须继承Comparable接口来达到自己的泛型实例之间能相互比较的目的。
public class BinarySearchTree<E extends Comparable<E>> //泛型参数不是实现接口,而是继承接口extends,
{
   
    //首先定义二分搜索树结点类
    private class Node
    {
   
        //将内部类的属性定义为public,这样外部类可以很容易操作他们
        public E e;
        public Node left , right;//指向左孩子与右孩子的指针

        public Node(E e)
        {
   
            this.e = e;
            left = null;
            right = null;
        }
    }


    //下面定义二分搜索树的属性:根节点、二分搜索树元素个数:size (外部类的属性必须定义为private)
    private Node root;
    private int size;
    //初始化二分搜索树,没有结点(根节点为null)
    public BinarySearchTree()
    {
   
        root = null;
        size = 0;
    }

    //树的元素个数
    public int size()
    {
   
        return size;
    }
    //树是否为空
    public boolean isEmpty()
    {
   
        return size==0;
    }

//----------------------------------------------------------------添加
    // 向二分搜索树中添加新的结点,结点的元素是e
    public void add(E e)
    {
   
        //如果根结点是null,创建一个新的结点对象 new Node(e) 赋予根结点
        if(root == null)
        {
   
            root = new Node(e);
            size++;//注意将树元素个数+1
        }
        else
        {
   //如果根结点不为null,以根结点为基础,进行结点的添加(二叉树都是从根结点展开的)
            //因为要进行递归添加,我们创建一个新的方法
            add(root, e);
        }
    }

    // 向以node为根的二分搜索树中插入结点(结点元素为e),递归算法。(这个方法不需要对用户暴露,因此设置为private)
    private void add(Node node, E e)
    {
   
        //E 类已经实现Comparable接口,具有比较性,使用equals()方法可以比较对象是否相等,使用compareTo()方法可以比较对象大小。

        /*
        1、解决最基本的问题(递归终止条件):如果添加的元素与二叉树某个结点的元素相等,不添加;否则在左还在或者右孩子找到一个合适的位置添加
        -------------------------------------------------
         */

        //如果要插入的数据与根结点的数据相同,直接结束添加(二分搜索树的子树的元素必须与根结点的元素不同!)
        if(e.equals(node.e))
            return;
        //如果新结点的元素e小于根结点元素,且左孩子为null,说明新的结点添加到左孩子的位置
        else if(e.compareTo(node.e)<0 && node.left==null)
        {
   
            node.left = new Node(e);
            size++;//注意将树元素个数+1
            return;//我们只添加一个,添加完毕后记得结束整个函数
        }
        //如果新结点的元素e大于根结点元素,且右孩子为null,说明新的结点添加到右孩子的位置
        else if(e.compareTo(node.e)>0 && node.right==null)
        {
   
            node.right = new Node(e);
            size++;
            return;
        
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值