树(二叉树的插入删除查找遍历)

树:由边连着节点而构成
根:树顶端的节点称为根,一棵树只有一个根
父节点:每个节点(除了根)都恰好有一条边向上连接到另一个节点,上面的这个节点就称为下面的节点的父节点
子节点:每个节点都可能有一条或多条向下连接的其他节点,下面的这些节点成为它的子节点
叶子节点:没有子节点的节点称为叶子节点
子树:每个节点都可以作为子树的根
二叉树:每个节点最多只能有两个节点
查询,插入,删除都很快(跟数组和链表相比)

public class Node {
    public int iData;//节点值(整数)
    public double dData;//节点值(小数)
    public Node leftChild;//子节点(左)
    public Node rightChild;//子节点(右)
    public void displayNode() {//以{iData,dData}的方式输出值
        System.out.print('{');
        System.out.print(iData);
        System.out.print(',');
        System.out.print(dData);
        System.out.print('}');
    }

}
import java.util.Stack;


public class Tree {
    private Node root;//根节点
    public Tree() {
        root=null;
    }
    //插入值
    public void insert(int id,double dd) {
        Node newNode=new Node();
        newNode.iData=id;
        newNode.dData=dd;
        if(root==null) {
            root=newNode;
        }else {
            Node current=root;//current标志当前节点
            Node parent;//parent标志当前节点发生变化后,之前的current节点就是父节点.
            while(true) {
                parent=current;
                if(id<current.iData) {//如果id是小的,就往左边找位置
                    current=current.leftChild;//一直往左边找,循环,直到左边没有找的了
                    if(current==null) {//即找到位置(循环的出口)
                        parent.leftChild=newNode;//插入数据
                        return;
                    }
                }else {//向右边找
                    current=current.rightChild;
                    if(current==null) {
                        parent.rightChild=newNode;
                        return;
                    }
                    
                }
            }
        }
    }
    //删除
    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) return false;//没找到
            
        }
        
        //删除
        if(current.leftChild==null && current.rightChild==null) {//删除的是叶子结点
            if(current==root)
                root=null;//删的是根(1)
            else if(isLeftChild) {//删除的是左子叶子
                parent.leftChild=null;//(2)
            }else {//删除的是右子叶子
                parent.rightChild=null;//(3)
            }
        }else if(current.rightChild==null) {//删除的节点不是叶子结点,然后删除的是只有左子树
            if(current==root)//(4)
                root=current.leftChild;//只用将根节点的左子节点标记为root就ok
            else if(isLeftChild)//(5)
                parent.leftChild=current.leftChild;//如果当前结点是父节点的左子节点,只用将父节点的左子节点标记为当前节点的左子节点
            else //(6)
                parent.rightChild=current.leftChild;//如果当前节点是父节点的右子节点,只用将父节点的有子节点标记为当前节点的左子节点
            
        }else if(current.leftChild==null) {//要删的节点只有右子树(与上面方法一样)
            if(current==root)//只用将根节点的右子节点标记为root就ok
                root=current.rightChild;//(7)
            else if(isLeftChild)
                parent.leftChild=current.rightChild;//(8)
            else parent.rightChild=current.rightChild;//(9)
        }else {//左右子树都有
            Node successor=getSuccessor(current);//寻找继承者
            if(current==root) root=successor;//如果当前结点是根(10)
            else if(isLeftChild)parent.leftChild=successor;//如果当前节点是左子节点(11)
            else parent.rightChild=successor;//(12)
            
            successor.leftChild=current.leftChild;//建立好替换后完整的树
        }
        return true;
        
    }
    //查找
    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 null;
            }
        }
        return current;
    }
    //遍历(三种方法)
        public void traverse(int traverseType) {
            switch(traverseType){
                case 1:
                    System.out.print("从上至下,从左至右:");
                    preOrder(root);
                    break;
                case 2:
                    System.out.print("从下至下,从左至右:");
                    inOrder(root);
                    break;
                case 3:
                    System.out.print("从下至上,从右至左:");
                    postOrder(root);
                    break;
                    
                    
            }
            System.out.println();
        }
    //找到继承者(树)
    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;//找delNode节点的右子树的左子节点
        }
        if(successor!=delNode.rightChild) {//将根为继承者的树建立好
            successorParent.leftChild=successor.rightChild;
            successor.rightChild=delNode.rightChild;
        }//如果是叶子,就不要建立树
        return successor;//返回继承者
    }
    //从上至下,从左至右
    private void preOrder(Node localRoot) {
        if(localRoot!=null) {
            System.out.print(localRoot.iData+" ");
            preOrder(localRoot.leftChild);
            preOrder(localRoot.rightChild);
        }
        
    }
    private void inOrder(Node localRoot) {
        if(localRoot!=null) {
            inOrder(localRoot.leftChild);
            System.out.print(localRoot.iData+" ");
            inOrder(localRoot.rightChild);
        }
    }
    private void postOrder(Node localRoot) {
        if(localRoot!=null) {
            postOrder(localRoot.leftChild);
            postOrder(localRoot.rightChild);
            System.out.print(localRoot.iData+" ");
            
        }
        
    }
    //显示一个树的结构
    public void dispalyTree() {
        Stack globalStack=new Stack();
        globalStack.push(root);//从这个栈里面要取的输出的值
        int nBlanks=32;//空格数
        boolean isRowEmpth=false;
        //树的开始分割线
        System.out.println("................................");
        while(isRowEmpth==false) {//当输出的节点有子节点时这个循环会继续执行
            Stack localStack=new Stack();//本地栈(存入当前节点的子节点,里面循环结束最后都倒入globalStack中)
            isRowEmpth=true;
            for(int j=0;j<nBlanks;j++)
                System.out.print(" ");//左边加32个空格
            while(!globalStack.isEmpty()) {//循环输出globalStack栈中的内容,每一次循环都将当前节点的子节点放入本地栈中
                Node temp=(Node)globalStack.pop();
                if(temp!=null) {//值为空就输出--,值不为空就输出值,并且值为空的节点肯定没有子节点。
                    System.out.print(temp.iData);
                    localStack.push(temp.leftChild);
                    localStack.push(temp.rightChild);
                    if(temp.leftChild!=null||temp.rightChild!=null)
                        isRowEmpth=false;//如果取出的值有子节点,就继续外层循环(如果当前节点没有子节点就不会进行下一次外层循环)
                }else {//空的数据项
                    System.out.print("--");
                    localStack.push(null);
                    localStack.push(null);
                }
                for(int j=0;j<nBlanks*2-2;j++) {
                    System.out.print(" ");
                }
            }
            System.out.println();
            nBlanks/=2;
            while(!localStack.isEmpty()) {
                globalStack.push(localStack.pop());
            }
        }
        //树的结束分割线
        System.out.println("--------------------------------------");
    }

}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {

        public static void main(String[] agrs) throws IOException {
            int value;
            Tree theTree=new Tree();
            theTree.insert(50, 1.5);
            theTree.insert(25, 1.5);
            theTree.insert(75, 1.5);
            theTree.insert(12, 1.5);
            theTree.insert(37, 1.5);
            theTree.insert(43, 1.5);
            theTree.insert(30, 1.5);
            theTree.insert(33, 1.5);
            theTree.insert(87, 1.5);
            theTree.insert(93, 1.5);
            theTree.insert(97, 1.5);
            while(true) {
                System.out.print("Enter first letter of show,isnert,find,delete,or traverse:");
                int choice=getchar();
                switch(choice){
                    case's':
                        theTree.dispalyTree();
                        break;
                    case 'i':
                        System.out.print("Enter value to insert:");
                        value=getInt();
                        theTree.insert(value, value+0.9);
                        break;
                    case 'f':
                        System.out.println("Enter value to find:");
                        value=getInt();
                        Node found=theTree.find(value);
                        if(found!=null) {
                            System.out.print("Found :");
                            found.displayNode();
                            System.out.println();
                        }else
                            System.out.print("not"+value);
                        break;
                    case 'd':
                        System.out.print("Enter value todelete:");
                        value=getInt();
                        boolean didDelete=theTree.delete(value);
                        if(didDelete)System.out.print("delete"+value);
                        else System.out.print("not "+value);
                        break;
                    case 't':
                        System.out.print("Enter 1,2 or 3:");
                        value=getInt();
                        theTree.traverse(value);
                        break;
                        default:
                            System.out.println("无效的输入");
                        
                        
                        
                }
            }
            
        }
        public static String getString()throws IOException{
            InputStreamReader isr=new InputStreamReader(System.in);
            BufferedReader br=new BufferedReader(isr);
            return br.readLine();
            }
        public static char getchar() throws IOException{
            return getString().charAt(0);
            
        }
        public static int getInt() throws IOException{
            String s=getString();
            return Integer.parseInt(s);
        }

    }
原文地址:https://www.cnblogs.com/S-Mustard/p/7730438.html