• java学习之—二叉树


    package com.data.java.towtree;
    
    import java.io.IOException;
    
    /**
     * 二叉树
     * @Title: uminton
     */
    
    class Node{
        public int iData; //数据用作关键值
        public double dData; //其他数据
        public Node leftChild; //左子节点
        public Node rightChild; //右子节点
    
        public Node() {
        }
    
        public Node(int iData, double dData) {
            this.iData = iData;
            this.dData = dData;
        }
    
        public void displayNode(){
            System.out.print("{");
            System.out.print(iData);
            System.out.print(", ");
            System.out.print(dData);
            System.out.print("} ");
        }
    }
    
    public class Tree {
    
        private Node root; //根节点
    
        public Node getRoot() {
            return root;
        }
    
        /**
         * 查找一个数据
         * @param key
         * @return
         */
        public Node find(int key){
            Node current = root;                 //把跟节点设置为当前节点
            while (current.iData != key){        //循环查找
                if(key < current.iData){         //如果小于就去当前树的左边子节点
                    current = current.leftChild; //把子节点赋给当前节点
                }else {                          //如果大于就去当前树的右边子节点
                    current = current.rightChild;//把子节点赋给当前节点
                }
                if(current == null){             //到达序列的末端没有找到节点,表明他不存在,返回空
                    return current;
                }
            }
            return current;                      //循环条件相等,循环结束,找到结果。
        }
    
        /**
         * 添加一个数据
         * @param id
         * @param dd
         */
        public void insert(int id, double dd) {
            Node newNode = new Node(id, dd);            //先创建一个新节点
            if(root == null){                           //如果跟节点为空,表示树,没有数据,直接赋值给根节点
                root = newNode;
            }else {
                Node current = root;                    //根节点赋值给当前节点,用于查找
                Node parent;                            //父节点,用来存储遇到的最后一个不是null的节点,因为curent在查找的过程中会变成null,
                                                        // 才能发现发现查找过得上一个节点没有子节点
                while (true){                           //循环查找
                    parent = current;                   //用来存储遇到的最后一个不是null的节点
                    if (id < current.iData){            //如果小于就去当前树的左边子节点
                        current = current.leftChild;
                        if(current == null){            //到达序列的末端没有找到节点,表明他不存在
                            parent.leftChild = newNode; //把新的节点赋值给父节点的左子节点
                            return;                     //直接返回,结束循环
                        }
                    }else {
                        current = current.rightChild;
                        if(current == null){
                            parent.rightChild = newNode;
                            return;
                        }
                    }
                }
            }
        }
    
        /**
         * 删除一个数据
         * @param key
         * @return
         *
         * 删除节点要考虑的三种情况
         * 1,该节点是叶节点
         * 2,该节点有一个子节点
         * 3,该节点有二个子节点
         */
        public boolean delete(int key){
            Node current = root;
            Node parent = root;
            boolean isLeftChild = true;             //记录是左节点还是右节点
            while(current.iData != key){            //循环为了找到要删除的节点,循环条件如果相等就是找到了,退出循环
                parent = current;                   //保存要删除的父节点
                if(key < current.iData){
                    isLeftChild = true;
                    current = current.leftChild;
                }else {
                    isLeftChild = false;
                    current = current.rightChild;
                }
                if(current == null){                //查找到末端,都没有找到,返回false
                    return false;
                }
            }
            /**************************情况1开始*********************************/
            if(current.leftChild == null && current.rightChild == null) {  //判断是否没有子节点,也就是该节点是叶节点
                if (current == root) {              //如果是根节点,直接赋值为null
                    root = null;
                } else if (isLeftChild) {           //判断是否是左节点
                    parent.leftChild = null;        //用上面保存的父节点找子节点,直接赋值为null
                } else {
                    parent.rightChild = null;
                }
            /**************************情况1结束*********************************/
    
            /**************************情况2开始*********************************/
            }else if (current.rightChild == null){      //判断左边等null或右边等于null
                if(current == root){                    //如果是根节点,直接赋值为null
                    root = current.leftChild;
                }else if (isLeftChild){                 //判断是否是左节点
                    parent.leftChild = current.leftChild;//用上面保存的父节点找子节点,直接赋值为null
                }else {
                    parent.rightChild = current.leftChild;
                }
            }else if (current.leftChild == null){       //下面同理
                if(current == root){
                    root = current.rightChild;
                }else if (isLeftChild){
                    parent.leftChild = current.rightChild;
                }else {
                    parent.rightChild = current.rightChild;
                }
            /**************************情况2结束*********************************/
    
            /**************************情况3开始*********************************/
            }else {                                     //上面都不成立,表明该节点有两个子节点。
                Node successor = getSuccessor(current); //取得后继者
                if(current == root){                    //如果是根节点,直接赋值为后继者
                    root = successor;
                }else if (isLeftChild){                 //判断是否是左节点
                    parent.leftChild = successor;       //用上面保存的父节点找子节点,直接赋值为后继者
                }else {
                    parent.rightChild = successor;
                }
                successor.leftChild = current.leftChild;
            }
            /**************************情况3结束*********************************/
            return true;
        }
    
        /**
         * 中序遍历树
         * @param localRoot
         */
        public void inOrder(Node localRoot){
            if(localRoot != null){
                inOrder(localRoot.leftChild);
                System.out.println(localRoot.iData);
                inOrder(localRoot.rightChild);
            }
        }
    
        /**
         * 查找最小值
         * @return
         */
        public Node minNumber(){
            Node current = root;
            Node last = null;
            while (current != null){
                last = current;
                current = current.leftChild;
            }
            return last;
        }
    
        /**
         * 获取删除节点的后继者
         * @param delNode
         * @return
         * 算法:程序找到要删除的节点的右子节点,(它的关键字值一定比要删除的节点的值大)然后转到右子节点的左子节点(若果有的话)
         * 然后到这个左子节点的左子节点,以此类推,这个路径的最后一个左子节点就是要删除节点的后继者
         * 若果删除节点右子节点没有左子节点,它就是后继者
         */
        private Node getSuccessor(Node delNode) {
            Node successorParent = delNode;
            Node successor = delNode;
            Node current = delNode.rightChild;          //删除节点右子节点
            while (current != null){
                successorParent = successor;            //保留后继者的父节点
                successor = current;                    //后继者
                current = current.leftChild;            //循环查找左子节点
            }
            if(successor != delNode.rightChild){
                successorParent.leftChild = successor.rightChild;
                successor.rightChild = delNode.rightChild;
            }
            return successor;
        }
    }
    
    class TreeApp{
        public static void main(String[] args) throws IOException {
            Tree treTree = new Tree();
            treTree.insert(38,1.5);
            treTree.insert(65,1.5);
            treTree.insert(40,1.5);
            treTree.insert(50,1.5);
            treTree.insert(55,1.5);
            treTree.insert(30,1.5);
            treTree.insert(90,1.5);
            treTree.insert(25,1.6);
            treTree.insert(70,1.7);
            treTree.insert(20,1.7);
            treTree.insert(80,1.7);
    
            treTree.delete(65);
    
        }
    }
    

      

    最后删除有点复杂,没怎么搞懂见谅。

  • 相关阅读:
    Linux -- 如何减少IO过程中的CPU copy
    Linux -- 在多线程程序中避免False Sharing
    智能文件选择列表—— bat 批处理
    Windows NTFS 符号链接 与 Linux 软连接
    【2017.12.12】deepin安装U盘制作,支持 BIOS+UEFI,deepin_Recovery+Win PE
    Qt creator中文输入—fctix-qt5 源码编译 libfcitxplatforminputcontextplugin.so
    安装 Qt 及所需 gcc 等
    虚拟机安装 deepin Linux 注意事项
    deepin 常用设置
    VIM常用快捷键
  • 原文地址:https://www.cnblogs.com/chancy/p/10827201.html
Copyright © 2020-2023  润新知