10 树结构基础部分

数组存储方式:
若数组添加元素,由于数组大小是固定的,所以每次存储,数组都会扩容创建新的数组,将原来数据拷贝到新的数组,并插入数据。
在这里插入图片描述
集合底层是用数组动态扩容。

在这里插入图片描述
在这里插入图片描述
以9为例,9比7大,放在7的右侧,9比10小,放在10左侧。

在这里插入图片描述

10.1.3 二叉树

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

package tree;

public class BinaryTreeDemo {
    
    

    public static void main(String[] args){
    
    
        //创建一棵二叉树
        BinaryTree binaryTree = new BinaryTree();
        //创建需要的节点
        HeroNode root = new HeroNode(1,"sj");
        HeroNode node2 = new HeroNode(2,"wy");
        HeroNode node3 = new HeroNode(3,"ljy");
        HeroNode node4 = new HeroNode(4,"lc");
        HeroNode node5 = new HeroNode(5,"gs");

        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);

        //c测试
        System.out.println("前序遍历");  //1,2,3,5,4
        binaryTree.setRoot(root);
        binaryTree.preOrder();

        System.out.println("中序遍历");  //2,1,5,3,4
        binaryTree.infixOrder();

        System.out.println("后序遍历");  //2,5,4,3,1
        binaryTree.postOrder();

    }
}

//定义二叉树
class BinaryTree{
    
    
    private HeroNode root;  //根节点

    public void setRoot(HeroNode root) {
    
    
        this.root = root;
    }

    //前序遍历
    public void preOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.preOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //中序遍历
    public void infixOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.infixOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //后序遍历
    public void postOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.postOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

}

//先创建HeroNode 节点
class HeroNode{
    
    
    private int no;
    private String name;
    private HeroNode left;  //默认null
    private HeroNode right;  //默认null

    public HeroNode(int no,String name){
    
    
        this.name = name;
        this.no = no;
    }

    public int getNo() {
    
    
        return no;
    }

    public void setNo(int no) {
    
    
        this.no = no;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public HeroNode getLeft() {
    
    
        return left;
    }

    public void setLeft(HeroNode left) {
    
    
        this.left = left;
    }

    public HeroNode getRight() {
    
    
        return right;
    }

    public void setRight(HeroNode right) {
    
    
        this.right = right;
    }

    @Override
    public String toString() {
    
    
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 前序遍历
     */
    public void preOrder(){
    
    
        System.out.println(this);  //先输入父节点
        //递归左子树  前序遍历
        if (this.left != null){
    
    
            this.left.preOrder();
        }
        //递归右子树  前序遍历
        if (this.right!=null){
    
    
            this.right.preOrder();
        }
    }

    /**
     * 中序遍历
     */
    public void infixOrder(){
    
    
        //递归左子树 中序遍历
        if (this.left!=null){
    
    
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归右子树 中序遍历
        if (this.right!=null){
    
    
            this.right.infixOrder();
        }
    }

    /**
     * 后序遍历
     */
    public void postOrder(){
    
    
        //递归左子树  后序遍历
        if (this.left!=null){
    
    
            this.left.postOrder();
        }
        //递归右子树  后序遍历
        if (this.right!=null){
    
    
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);
    }
}

前序遍历:父–>左子树–>右子树
中序遍历:左子树–>父–>右子树
后序遍历:左子树–>右子树–>父

10.1.6 二叉树查找节点

在这里插入图片描述

package tree;

public class BinaryTreeDemo {
    
    

    public static void main(String[] args){
    
    
        //创建一棵二叉树
        BinaryTree binaryTree = new BinaryTree();
        //创建需要的节点
        HeroNode root = new HeroNode(1,"sj");
        HeroNode node2 = new HeroNode(2,"wy");
        HeroNode node3 = new HeroNode(3,"ljy");
        HeroNode node4 = new HeroNode(4,"lc");
        HeroNode node5 = new HeroNode(5,"gs");

        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);

        //c测试
        System.out.println("前序遍历");  //1,2,3,5,4
        binaryTree.setRoot(root);
        binaryTree.preOrder();

        System.out.println("中序遍历");  //2,1,5,3,4
        binaryTree.infixOrder();

        System.out.println("后序遍历");  //2,5,4,3,1
        binaryTree.postOrder();

        System.out.println("前序遍历查找");  //1,2,3,5,4
        HeroNode resNode = binaryTree.preOrderSearch(5);
        if (resNode!=null){
    
    
            System.out.printf("找到,no = %d name = %s",resNode.getNo(),resNode.getName());
        }else {
    
    
            System.out.println("没有找到");
        }

        System.out.println("中序遍历查找");  //1,2,3,5,4
        HeroNode resNode2 = binaryTree.infixOrderSearch(5);
        if (resNode2!=null){
    
    
            System.out.printf("找到,no = %d name = %s",resNode2.getNo(),resNode2.getName());
        }else {
    
    
            System.out.println("没有找到");
        }

        System.out.println("后序遍历查找");  //1,2,3,5,4
        HeroNode resNode3 = binaryTree.infixOrderSearch(5);
        if (resNode3!=null){
    
    
            System.out.printf("找到,no = %d name = %s",resNode3.getNo(),resNode3.getName());
        }else {
    
    
            System.out.println("没有找到");
        }

    }
}

//定义二叉树
class BinaryTree{
    
    
    private HeroNode root;  //根节点

    public void setRoot(HeroNode root) {
    
    
        this.root = root;
    }

    //前序遍历
    public void preOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.preOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //中序遍历
    public void infixOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.infixOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //后序遍历
    public void postOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.postOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //前序遍历查找
    public HeroNode preOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.postOrderSearch(no);
        }else {
    
    
            return null;
        }
    }

    //中序遍历查找
    public HeroNode infixOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.infixOrderSearch(no);
        }else {
    
    
            return null;
        }
    }

    //后续遍历查找
    public HeroNode postOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.postOrderSearch(no);
        }else {
    
    
            return null;
        }
    }
}

//先创建HeroNode 节点
class HeroNode{
    
    
    private int no;
    private String name;
    private HeroNode left;  //默认null
    private HeroNode right;  //默认null

    public HeroNode(int no,String name){
    
    
        this.name = name;
        this.no = no;
    }

    public int getNo() {
    
    
        return no;
    }

    public void setNo(int no) {
    
    
        this.no = no;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public HeroNode getLeft() {
    
    
        return left;
    }

    public void setLeft(HeroNode left) {
    
    
        this.left = left;
    }

    public HeroNode getRight() {
    
    
        return right;
    }

    public void setRight(HeroNode right) {
    
    
        this.right = right;
    }

    @Override
    public String toString() {
    
    
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 前序遍历
     */
    public void preOrder(){
    
    
        System.out.println(this);  //先输入父节点
        //递归左子树  前序遍历
        if (this.left != null){
    
    
            this.left.preOrder();
        }
        //递归右子树  前序遍历
        if (this.right!=null){
    
    
            this.right.preOrder();
        }
    }

    /**
     * 中序遍历
     */
    public void infixOrder(){
    
    
        //递归左子树 中序遍历
        if (this.left!=null){
    
    
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归右子树 中序遍历
        if (this.right!=null){
    
    
            this.right.infixOrder();
        }
    }

    /**
     * 后序遍历
     */
    public void postOrder(){
    
    
        //递归左子树  后序遍历
        if (this.left!=null){
    
    
            this.left.postOrder();
        }
        //递归右子树  后序遍历
        if (this.right!=null){
    
    
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);
    }

    //前序遍历查找
    public HeroNode preOrderSearch(int no){
    
    
        //比较当前节点是不是
        if (this.no == no){
    
    
            return this;
        }
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.preOrderSearch(no);
        }
        if (resNode!=null){
    
      //左子树找到
            return resNode;
        }
        if (this.right!=null){
    
    
            resNode = this.right.preOrderSearch(no);
        }
        return resNode;
    }

    //中序遍历查找
    public HeroNode infixOrderSearch(int no){
    
    
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.infixOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return resNode;
        }
        if (this.no == no){
    
    
            return this;
        }
        if (this.right!=null){
    
    
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    //后续遍历查找
    public HeroNode postOrderSearch(int no){
    
    
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.postOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return resNode;
        }
        if (this.right!=null){
    
    
            resNode = this.right.postOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return  resNode;
        }
        if (this.no == no){
    
    
            return this;
        }
        return resNode;
    }

}

二叉树删除节点

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

package tree;

public class BinaryTreeDemo {
    
    

    public static void main(String[] args){
    
    
        //创建一棵二叉树
        BinaryTree binaryTree = new BinaryTree();
        //创建需要的节点
        HeroNode root = new HeroNode(1,"sj");
        HeroNode node2 = new HeroNode(2,"wy");
        HeroNode node3 = new HeroNode(3,"ljy");
        HeroNode node4 = new HeroNode(4,"lc");
        HeroNode node5 = new HeroNode(5,"gs");

        root.setLeft(node2);
        root.setRight(node3);
        node3.setRight(node4);
        node3.setLeft(node5);

        binaryTree.setRoot(root);
       
        //测试删除节点
        System.out.println("删除前,前序遍历");
        binaryTree.preOrder();
        binaryTree.delNode(3);
        System.out.println("删除后,前序遍历");
        binaryTree.preOrder();
    }
}

//定义二叉树
class BinaryTree{
    
    
    private HeroNode root;  //根节点

    public void setRoot(HeroNode root) {
    
    
        this.root = root;
    }

    //删除节点
    public void delNode(int no){
    
    
        if (root!=null){
    
    
            //如果只有一个root节点,判断root是不是要删除的节点
            if (root.getNo()==no){
    
    
                root = null;
            }else {
    
    
                //递归删除
                root.delNode(no);
            }
        }else {
    
    
            System.out.println("空树不能删除");
        }
    }

    //前序遍历
    public void preOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.preOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //中序遍历
    public void infixOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.infixOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //后序遍历
    public void postOrder(){
    
    
        if (this.root!=null){
    
    
            this.root.postOrder();
        }else {
    
    
            System.out.println("二叉树为空,无法遍历");
        }
    }

    //前序遍历查找
    public HeroNode preOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.postOrderSearch(no);
        }else {
    
    
            return null;
        }
    }

    //中序遍历查找
    public HeroNode infixOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.infixOrderSearch(no);
        }else {
    
    
            return null;
        }
    }

    //后续遍历查找
    public HeroNode postOrderSearch(int no){
    
    
        if (root!=null){
    
    
            return root.postOrderSearch(no);
        }else {
    
    
            return null;
        }
    }
}

//先创建HeroNode 节点
class HeroNode{
    
    
    private int no;
    private String name;
    private HeroNode left;  //默认null
    private HeroNode right;  //默认null

    public HeroNode(int no,String name){
    
    
        this.name = name;
        this.no = no;
    }

    public int getNo() {
    
    
        return no;
    }

    public void setNo(int no) {
    
    
        this.no = no;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public HeroNode getLeft() {
    
    
        return left;
    }

    public void setLeft(HeroNode left) {
    
    
        this.left = left;
    }

    public HeroNode getRight() {
    
    
        return right;
    }

    public void setRight(HeroNode right) {
    
    
        this.right = right;
    }

    @Override
    public String toString() {
    
    
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 递归删除节点
     *      如果删除的是叶子节点,则删除该节点
     *      如果删除的是非叶子节点,删除该子树
     * @param no
     */
    public void delNode(int no){
    
    
        //判断左子节点
        if (this.left!=null && this.left.no==no){
    
    
            this.left = null;
            return;
        }
        //判断右子节点
        if (this.right!=null && this.right.no==no){
    
    
            this.right = null;
            return;
        }
        //左子树递归删除
        if (this.left!=null){
    
    
            this.left.delNode(no);
        }
        //右子树递归删除
        if (this.right!=null){
    
    
            this.right.delNode(no);
        }
    }

    /**
     * 前序遍历
     */
    public void preOrder(){
    
    
        System.out.println(this);  //先输入父节点
        //递归左子树  前序遍历
        if (this.left != null){
    
    
            this.left.preOrder();
        }
        //递归右子树  前序遍历
        if (this.right!=null){
    
    
            this.right.preOrder();
        }
    }

    /**
     * 中序遍历
     */
    public void infixOrder(){
    
    
        //递归左子树 中序遍历
        if (this.left!=null){
    
    
            this.left.infixOrder();
        }
        //输出父节点
        System.out.println(this);
        //递归右子树 中序遍历
        if (this.right!=null){
    
    
            this.right.infixOrder();
        }
    }

    /**
     * 后序遍历
     */
    public void postOrder(){
    
    
        //递归左子树  后序遍历
        if (this.left!=null){
    
    
            this.left.postOrder();
        }
        //递归右子树  后序遍历
        if (this.right!=null){
    
    
            this.right.postOrder();
        }
        //输出父节点
        System.out.println(this);
    }

    //前序遍历查找
    public HeroNode preOrderSearch(int no){
    
    
        //比较当前节点是不是
        if (this.no == no){
    
    
            return this;
        }
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.preOrderSearch(no);
        }
        if (resNode!=null){
    
      //左子树找到
            return resNode;
        }
        if (this.right!=null){
    
    
            resNode = this.right.preOrderSearch(no);
        }
        return resNode;
    }

    //中序遍历查找
    public HeroNode infixOrderSearch(int no){
    
    
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.infixOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return resNode;
        }
        if (this.no == no){
    
    
            return this;
        }
        if (this.right!=null){
    
    
            resNode = this.right.infixOrderSearch(no);
        }
        return resNode;
    }

    //后续遍历查找
    public HeroNode postOrderSearch(int no){
    
    
        HeroNode resNode = null;
        if (this.left!=null){
    
    
            resNode = this.left.postOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return resNode;
        }
        if (this.right!=null){
    
    
            resNode = this.right.postOrderSearch(no);
        }
        if (resNode!=null){
    
    
            return  resNode;
        }
        if (this.no == no){
    
    
            return this;
        }
        return resNode;
    }

}

10.2 顺序存储二叉树

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

package tree.ArrBinaryTree;

public class ArrBinaryTreeDemo {
    
    
    public static void main(String[] args){
    
    
        int[] arr = {
    
    1,2,3,4,5,6,7};
        //创建tree
        ArrBinaryTree arrBinaryTree = new ArrBinaryTree(arr);
        System.out.println("前序");
        arrBinaryTree.preOrder();  // 1245367
        System.out.println("中序");
        arrBinaryTree.midOrder();
        System.out.println("后序");
        arrBinaryTree.laOrder();
    }
}


package tree.ArrBinaryTree;

//实现顺序存储二叉树遍历
public class ArrBinaryTree {
    
    
    private int[] arr; //存储数据节点的数组

    public ArrBinaryTree(int[] arr){
    
    
        this.arr = arr;
    }

    //重载
    public void preOrder(){
    
    
        this.preOrder(0);
    }
    public void midOrder(){
    
    
        this.midOrder(0);
    }
    public void laOrder(){
    
    
        this.laOrder(0);
    }

    /**
     * //编写方法,完成顺序存储二叉树的前序遍历
     * @param index  数组下标
     */
    public void preOrder(int index){
    
    
        //如果数组为空,或者arr.length = 0
        if (arr==null || arr.length==0){
    
    
            System.out.println("数组为空,无法遍历");
        }
        //输出当前元素
        System.out.println(arr[index]);
        //向左递归遍历
        if ((index*2)+1<arr.length){
    
    
            preOrder(2*index+1);
        }
        //向右递归
        if ((index*2)+2 < arr.length){
    
    
            preOrder(2*index+2);
        }
    }

    /**
     * 中序遍历
     * @param index
     */
    public void midOrder(int index){
    
    
        if (arr==null || arr.length==0){
    
    
            System.out.println("数组为空,无法遍历");
        }
        //左递归遍历
        if ((index*2)+1<arr.length){
    
    
            midOrder(2*index+1);
        }
        //输出当前元素
        System.out.println(arr[index]);
        //右递归
        if ((index*2)+2<arr.length){
    
    
            midOrder(2*index+2);
        }
    }

    /**
     * 后序遍历
     * @param index
     */
    public void laOrder(int index){
    
    
        if (arr==null||arr.length==0){
    
    
            System.out.println("数组为空,无法遍历");
        }
        //左递归
        if ((index*2)+1 < arr.length){
    
    
            laOrder(2*index+1);
        }
        //右递归
        if ((index*2+2) < arr.length){
    
    
            laOrder(2*index+2);
        }
        //输出
        System.out.println(arr[index]);
    }
}

10.3 线索化二叉树

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

package tree.ThreadedTree;

public class ThreadBinaryTreeDemo {
    
    
    public static void main(String[] args){
    
    
        //测试
        HeroNode root = new HeroNode(1, "a");
        HeroNode node2 = new HeroNode(3, "c");
        HeroNode node3 = new HeroNode(6, "a6");
        HeroNode node4 = new HeroNode(8, "a8");
        HeroNode node5 = new HeroNode(10, "a10");
        HeroNode node6 = new HeroNode(14, "a14");

        //二叉树,创建
        root.setLeft(node2);
        root.setRight(node3);
        node2.setLeft(node4);
        node2.setRight(node5);
        node3.setLeft(node6);

        //线索化
        ThreadedBinaryTree threadedBinaryTree = new ThreadedBinaryTree();
        threadedBinaryTree.setRoot(root);
        threadedBinaryTree.threadedNodes();

        //测试:10号节点
        HeroNode leftNode = node5.getLeft();
        System.out.println("10号节点的前驱节点是:" + leftNode);  //3 c
        HeroNode rightNode = node5.getRight();
        System.out.println("10号节点的后继节点是:" + rightNode);//1 a
    }
}


package tree.ThreadedTree;

public class ThreadedBinaryTree {
    
    
    private HeroNode root;

    //为实现线索化,需要创建要给指向当前节点的前驱节点的指针
    //在递归进行线索化时,pre总是保留前一个节点
    private HeroNode pre = null;

    public void setRoot(HeroNode root) {
    
    
        this.root = root;
    }
    //重载线索化
    public void threadedNodes(){
    
    
        this.threadedNodes(root);
    }

    /**
     * 二叉树中序线索化方法
     * @param node 当前需要线索化的方法
     */
    public void threadedNodes(HeroNode node){
    
    
        if (node == null){
    
    
            return;
        }

        // 1. 先线索化左子树
        threadedNodes(node.getLeft());
        // 2. 线索化当前节点

        //处理当前节点的前驱节点
        if (node.getLeft() == null){
    
    
            //让当前节点的左指针指向前驱节点
            node.setLeft(pre);
            //修改当前节点的做针织类型,指向前驱节点
            node.setLeftType(1);
        }

        //处理后继节点
        if (pre!=null &&pre.getRight()==null){
    
    
            //让前驱节点的右指针指向当前节点
            pre.setRight(node);
            //修改前驱节点的右指针类型
            pre.setRightType(1);
        }
        //每处理一个节点后,让当前节点是下一个节点的前驱节点
        pre = node;

        // 3. 线索化右子树
        threadedNodes(node.getRight());
    }
}


package tree.ThreadedTree;

public class HeroNode {
    
    
    private int no;
    private String name;
    private HeroNode left;
    private HeroNode right;

    // 0 左子树   1 前驱节点
    private int leftType;
    // 0 右子树   1 后继节点
    private int rightType;

    public HeroNode(int no,String name){
    
    
        this.no = no;
        this.name = name;
    }

    public int getNo() {
    
    
        return no;
    }

    public void setNo(int no) {
    
    
        this.no = no;
    }

    public String getName() {
    
    
        return name;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    public HeroNode getLeft() {
    
    
        return left;
    }

    public void setLeft(HeroNode left) {
    
    
        this.left = left;
    }

    public HeroNode getRight() {
    
    
        return right;
    }

    public void setRight(HeroNode right) {
    
    
        this.right = right;
    }

    public int getLeftType() {
    
    
        return leftType;
    }

    public void setLeftType(int leftType) {
    
    
        this.leftType = leftType;
    }

    public int getRightType() {
    
    
        return rightType;
    }

    public void setRightType(int rightType) {
    
    
        this.rightType = rightType;
    }

    @Override
    public String toString() {
    
    
        return "HeroNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }
}

猜你喜欢

转载自blog.csdn.net/qq_41997237/article/details/116255642