数据结构 二叉树

本文介绍了二叉树的基本概念,包括结点的度、树的度、子结点、父结点等,以及有序树和无序树的定义。接着详细阐述了二叉树的特点,强调每个节点最多有两个子节点。插入、查找和修改节点的操作,以及前序、中序和后序遍历二叉树的方法也进行了说明,并以实例展示了遍历的序列。

1.树的术语

(1)结点的度:一个结点拥有子树(或后继结点)的个数称为度.度是结点分支树的表示.
(2)树的度:树中所有结点的度的最大值称为树的度.
(3)子结点:一个结点的子树的根节点(或直接后继结点)称为该结点的子结点.
(4)父结点:一棵子树根结点的前继结点称为父结点.除根结点以外的任何结点有且仅有一个父结点.父结点也称双亲结点.
(5)兄弟结点:属于同一个父结点的若干子结点之间互称兄弟结点.
(6)结点的层:树的任何一个结点都处于某一层.因此,树中结点构成一个层次结构.
(7)树的深度:树的最大层次数称为树的深度,也称树的高度.
(8)有序树和无序数:若把结点的子结点都看成从左向右是有序的,则称为有序树;否则称为无序树.有序树的兄弟结点不可交换.
(9)森林:树的集合称为森林.树和森林之间有着密切的关系.删除一个树的根结点,其所有原来的子树都是树,构成森林.用一个结点连接到森林的所有树的根结点就构成树.这个结点称为新的根结点.森林的所有树是该结点的子树.

2.二叉树

核心:树中每个节点最多只能有两个子节点。当每个子节点都有两个孩子的时候,叫做满二叉树。

插入结点核心:
1)如果不存在节点,则直接插入;
2)从根开始查找一个相应的节点,即新节点的父节点,当父节点被找到后,根据新节点的值来确定新节点是连接到左子节点还是右子节点。

查找节点核心:
1)从根开始查找,
2)如果查找节点值比父节点小,则查找其左子树,
3)否则查找右子树,直到找到为止,
4)如果不存在节点,返回Null

修改节点核心:
1)查找节点
2)找到该节点后,修改值(一般不建议修改keyData)

遍历二叉树核心:

三种方法::先序,中序,后序
序是针对父节点(根节点)的位置

前序:根结点第一个访问,然后访问左、右孩子;ABC
后序:根结点最后访问,开始先访问左、右孩子;BCA
中序:根结点第二个访问,最先访问左孩子,最后访问右孩子;BAC
以下图为例子:
这里写图片描述
前序序列:0134256
后序序列:3415620
中序序列:3140526

先序遍历二叉树:
1)访问节点;
2)先序遍历节点的左子树;
3)先序遍历节点的右子树。

中序遍历二叉树:
1)中序遍历节点的左子树;
2)访问节点;
3)中序遍历节点的右子树。

后序遍历二叉树:
1)后序遍历节点的左子树;
2)后序遍历节点的右子树;
3)访问节点。

3.代码实现二叉树

public class Node {
    //关键字
    private int keyData;

    //其他数据
    private int otherData;

    //左子节点
    private Node leftNode;
    //右子节点
    private Node rightNode;

    //构造方法
    public Node(int keyData,int otherData){
        this.keyData=keyData;
        this.otherData=otherData;
    }

    public int getKeyData() {
        return keyData;
    }

    public void setKeyData(int keyData) {
        this.keyData = keyData;
    }

    public int getOtherData() {
        return otherData;
    }

    public void setOtherData(int otherData) {
        this.otherData = otherData;
    }

    public Node getLeftNode() {
        return leftNode;
    }

    public void setLeftNode(Node leftNode) {
        this.leftNode = leftNode;
    }

    public Node getRightNode() {
        return rightNode;
    }

    public void setRightNode(Node rightNode) {
        this.rightNode = rightNode;
    }

    //显示方法
    public void display(){
        System.out.println(this.keyData+","+this.otherData);
    }
}

public class Tree {
    //根
    private Node root;

    //插入方法
    public void insert(int keyData,int otherData){
        Node newNode=new Node(keyData,otherData);
        //如果没有节点
        if(root==null){
            root=newNode;
        }else{
            //有节点:先跟根节点比较
            Node current=root;
            Node parent;
            while (true) {
                parent=current;
                if (keyData < current.getKeyData()) {
                    //小于根节点,放左边,跟左子节点比较
                    current = current.getLeftNode();
                    if(current==null){
                        parent.setLeftNode(newNode);
                        return;
                    }
                } else {
                    //>=根节点,放右边,跟右子节点比较
                    current = current.getRightNode();
                    if(current==null){
                        parent.setRightNode(newNode);
                        return;
                    }
                }
            }
        }
    }

    //查找方法
    public Node find(int keyData){
        Node current=root;
        //从根节点开始查找,比较查找值和当前节点
        while(current.getKeyData()!=keyData){
            if(keyData<current.getKeyData()){
                current=current.getLeftNode();//往左子树找
            }else{
                current=current.getRightNode();//往右子树找
            }
            if(current==null){
                //找不到了,返回Null
                return null;
            }
        }
        return current;
    }

    //删除方法
    public void delete(int KeyData){

    }

    //修改方法
    public void change(int keyData,int newOtherData){
        Node findNode=find(keyData);
        findNode.setOtherData(newOtherData);
    }

    //遍历方法
    //先序遍历
    public void preOrder(Node node){
        if(node!=null){
            node.display();
            preOrder(node.getLeftNode());
            preOrder(node.getRightNode());
        }   
    }

    //中序遍历
    public void inOrder(Node node){
        if(node!=null){
            inOrder(node.getLeftNode());
            node.display();
            inOrder(node.getRightNode());
        }   
    }

    //后序遍历
    public void endOrder(Node node){
        if(node!=null){
            endOrder(node.getLeftNode());
            endOrder(node.getRightNode());
            node.display();
        }   
    }

    public Node getRoot(){
        return root;
    }
}

public class TestTree {
    public static void main(String[] args) {
        Tree tree=new Tree();
        //插入节点
        tree.insert(1,1);
        tree.insert(2,41);
        tree.insert(3,3);

        Node findNode=tree.find(2);
        findNode.display();//查找:2,41
        tree.change(2,44);
        findNode.display();//修改为:2,44

        //遍历
        tree=new Tree();
        tree.insert(80, 80);
        tree.insert(49, 49);
        tree.insert(42, 42);
        tree.insert(30, 30);
        tree.insert(45, 45);
        tree.insert(90, 90);
        tree.insert(150, 150);
        tree.insert(130, 130);
        tree.insert(82, 82);
        tree.preOrder(tree.getRoot());
        //先序:80,49,42,30,45,90,82,150,130
        tree.inOrder(tree.getRoot());
        //中序:30,42,45,49,80,82,90,130,150
        tree.inOrder(tree.getRoot());
        //后序:30,45,42,49,82,130,150,90,80
    }

}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值