树结构一

树的一些概念

根节点,双亲节点,子节点,路径,节点的度,节点的权,叶子节点,子树,层,数的高度,森林

二叉树

定义

任何一个节点的子节点数量不超过2
二叉树的子节点分左节点和右节点,不能随意颠倒

  • 满二叉树
    所有叶子节点都在最后一层,而且节点的总数为 2 n − 1 2^n-1 2n1,n是树的高度
  • 完全二叉树
    所有叶子节点都在最后一层或倒数第二层,且最后一层的叶子节点在左边连续,倒数第二层的叶子节点在右边连续
链式存储的二叉树
  • 创建二叉树代码实现:
package com.test;

public class BinaryTree {

    TreeNode root;

    //设置根节点
    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public TreeNode getRoot() {
        return root;
    }
}

package com.test;

public class TreeNode {

    //节点的权
    int value;

    //左儿子
    TreeNode leftNode;
    //右儿子
    TreeNode rightNode;

    public TreeNode(int value){
        this.value = value;
    }

    //设置左儿子
    public void setLeftNode(TreeNode leftNode) {
        this.leftNode = leftNode;
    }

    //设置右儿子
    public void setRightNode(TreeNode rightNode) {
        this.rightNode = rightNode;
    }
}

public static void main(String[] args) {
		BinaryTree binaryTree = new BinaryTree();
		//创建一个根节点
		TreeNode root = new TreeNode(1);
		binaryTree.setRoot(root);
		//创建两个节点
		TreeNode rootL = new TreeNode(2);
		//把新节点设置为根节点的子节点
		root.setLeftNode(rootL);
		TreeNode rootR = new TreeNode(3);
		//把新节点设置为根节点的子节点
		root.setRightNode(rootR);
	}
  • 遍历二叉树
    如图二叉树
  1. 前序遍历:节点,节点的左子节点,节点的右子节点
    遍历顺序: 1 2 4 5 3 6 7
  2. 中序遍历:节点的左子节点,节点,节点的右子节点
    遍历顺序: 4 2 5 1 6 3 7
  3. 后序遍历:节点的左子节点,节点的右子节点,节点
    遍历顺序: 4 5 2 6 7 3 1
    代码实现:
package com.test;

public class Test {

    public static void main(String[] args) {
        BinaryTree binaryTree = new BinaryTree();
        //创建一个根节点
        TreeNode root = new TreeNode(1);
        binaryTree.setRoot(root);
        //创建两个节点
        TreeNode rootL = new TreeNode(2);
        //把新节点设置为根节点的子节点
        root.setLeftNode(rootL);
        TreeNode rootR = new TreeNode(3);
        //把新节点设置为根节点的子节点
        root.setRightNode(rootR);
        rootL.setLeftNode(new TreeNode(4));
        rootL.setRightNode(new TreeNode(5));
        rootR.setLeftNode(new TreeNode(6));
        rootR.setRightNode(new TreeNode(7));
        //前序遍历树
        binaryTree.frontShow();
        System.out.println("=====================");
        //中序遍历树
        binaryTree.middleShow();
        System.out.println("=====================");
        //后序遍历树
        binaryTree.afterShow();
    }
}
package com.test;

public class BinaryTree {

    TreeNode root;

    //设置根节点
    public void setRoot(TreeNode root) {
        this.root = root;
    }

    public TreeNode getRoot() {
        return root;
    }

    public void frontShow(){
        root.frontShow();
    }

    public void middleShow(){
        root.middleShow();
    }

    public void afterShow(){
        root.afterShow();
    }
}
package com.test;

public class TreeNode {

    //节点的权
    int value;

    //左儿子
    TreeNode leftNode;
    //右儿子
    TreeNode rightNode;

    public TreeNode(int value){
        this.value = value;
    }

    //设置左儿子
    public void setLeftNode(TreeNode leftNode) {
        this.leftNode = leftNode;
    }

    //设置右儿子
    public void setRightNode(TreeNode rightNode) {
        this.rightNode = rightNode;
    }


    //前序遍历
    public void frontShow(){
        //先遍历当前节点的内容
        System.out.println(value);
        //左节点
        if (leftNode != null){
            leftNode.frontShow();
        }
        //右节点
        if (rightNode != null){
            rightNode.frontShow();
        }
    }

    //中序遍历
    public void middleShow() {
        //左节点
        if (leftNode != null){
            leftNode.middleShow();
        }
        //遍历当前节点的内容
        System.out.println(value);
        //右节点
        if (rightNode != null){
            rightNode.middleShow();
        }
    }

    public void afterShow() {
        //左节点
        if (leftNode != null){
            leftNode.afterShow();
        }
        //右节点
        if (rightNode != null){
            rightNode.afterShow();
        }
        //遍历当前节点的内容
        System.out.println(value);
    }
}
  • 二叉树节点查找
//前序查找
TreeNode result = binaryTree.frontSearch(5);
System.out.println(result);
//前序查找
public TreeNode frontSearch(int i) {
    TreeNode target = null;
    //对比当前节点的值
    if (this.value == i){
        return this;
        //当前节点不是要查找的值
    }else {
        //查找左儿子
        if (leftNode != null){
            //有可能可以查到,也可以查不到,查不到的话,target还是null
            target = leftNode.frontSearch(i);
        }
        if (target != null){
            return target;
        }
        if (rightNode != null){
            target = rightNode.frontSearch(i);
        }
    }
    return target;
}
  • 删除节点
public void delete(int i) {
        if (root.value == i){
            root = null;
        }else{
            root.delete(i);
        }
    }
//删除子树
    public void delete(int i) {
        TreeNode parent = this;
        //判断左儿子
        if (parent.leftNode.value == i){
            parent.leftNode = null;
            return;
        }
        //判断右儿子
        if (parent.rightNode.value == i){
            parent.rightNode = null;
            return;
        }
        //递归检查并删除左儿子
        parent = leftNode;
        if (parent != null){
            parent.delete(i);
        }
        //递归检查并删除右儿子
        parent = rightNode;
        if (parent != null){
            parent.delete(i);
        }
    }
顺序存储的二叉树

顺序存储的二叉树通常情况下只考虑完全二叉树
第n个元素的左子节点是: 2 ∗ n + 1 2*n+1 2n+1
第n个元素的右子节点是: 2 ∗ n + 2 2*n+2 2n+2
第n个元素的父节点是: ( n − 1 ) / 2 (n-1)/2 (n1)/2
代码实现:

package com.test;

public class ArrayBinaryTree {

    int[] data;

    public ArrayBinaryTree(int[] data){
        this.data=data;
    }

    public void frontShow(){
        frontShow(0);
    }
    //前序遍历
    public void frontShow(int start){
        if (data ==null || data.length == 0){
            return;
        }
        //先遍历当前节点的内容
        System.out.println(data[start]);
        //左节点
        if (2*start+1<data.length){
            frontShow(2*start+1);
        }
        //右节点
        if (2*start+2<data.length){
            frontShow(2*start+2);
        }
    }
}
public static void main(String[] args) {
    int[] data = new int[]{1,2,3,4,5,6,7};
    ArrayBinaryTree arrayBinaryTree = new ArrayBinaryTree(data);
    arrayBinaryTree.frontShow();
}

运行结果:

1
2
4
5
3
6
7
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值