数据结构学习(五):二叉树

版权声明:文章为作者原创,若要转载请获得作者同意。尊重版权,从你我做起! https://blog.csdn.net/qq_37768971/article/details/88376363

一、学习目标:使用递归的思想完成二叉树基本功能的实现

二、实现的方法:

0.构造方法

public class BST <E extends Comparable<E>>{

    private class Node{   //定义节点为私有类(用户不需要知道)
        public E e;
        public Node left;
        public Node right;
        public Node(E e){
            this.e=e;
            this.left=null;
            this.right=null;
        }
    }

    private Node root;
    private int size;
    public BST(){
        root=null;
        size=0;
    }
}

1.isEmpty

    //判断二叉树是否为空
    public boolean isEmpty(){
        return size==0;
    }

2.getSize

    //获得二叉树元素的个数
    public int getSize(){
        return size;
    }

3.add

    //在二叉树中添加元素(自动按照大小排序)
    public void add(E e){
        root=add(root,e);
    }
    private Node add(Node node,E e){
        if(node==null){
            size++;
            return new Node(e);
        }
        else if (e.compareTo(node.e)<0)node.left=add(node.left,e);//此处注意:要把当前节点的左边引用指向新增的节点
        else node.right=add(node.right,e);
        return node;
    }

4.contian

    //判断二叉树中是否含有e
    public boolean contian(E e){
        return contain(root,e);
    }

5.遍历

 //前序遍历
    public void preOrder(){
        preOrder(root);
    }
    private void preOrder(Node node){
        if (node==null)return ;
            System.out.println(node.e);
            preOrder(node.left);
            preOrder(node.right);
    }
    //非递归算法
    public void preOrderNR(){

    if(root == null)
        return;

    Stack<Node> stack = new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()){
        Node cur = stack.pop();
        System.out.println(cur.e);

        if(cur.right != null)
            stack.push(cur.right);
        if(cur.left != null)
            stack.push(cur.left);
    }
}
    //中序遍历
    public void inOrder(){
        inOrder(root);
    }
    private void inOrder(Node node){
        if (node==null)return;
        inOrder(node.left);
        System.out.println(node.e);
        inOrder(node.right);
    }
    //后序遍历
    public void  postOrder(){
        postOrder(root);
    }
    private void postOrder(Node node){
        if (node==null){
            return;
        }
        postOrder(node.left);
        postOrder(node.right);
        System.out.println(node.e);
    }
    //层序遍历
    public void levelOrder(){
        Queue <Node>lel=new LinkedList<>();
        if (root==null)return;
        lel.add(root);
        while (!lel.isEmpty()){
            Node cur=lel.remove();
            System.out.println(cur.e);
            if (cur.left!=null)lel.add(cur.left);
            if (cur.right!=null)lel.add(cur.right);
        }
    }

6.搜索最大最小值

    // 寻找二分搜索树的最小元素
    public E minimum(){
        if(size == 0)
            throw new IllegalArgumentException("BST is empty");

        Node minNode = minimum(root);
        return minNode.e;
    }
    private Node minimum(Node node){
        if( node.left == null )
            return node;

        return minimum(node.left);
    }

    // 寻找二分搜索树的最大元素
    public E maximum(){
        if(size == 0)
            throw new IllegalArgumentException("BST is empty");

        return maximum(root).e;
    }
    private Node maximum(Node node){
        if( node.right == null )
            return node;

        return maximum(node.right);
    }

7.删除二叉树中的元素

扫描二维码关注公众号,回复: 5510269 查看本文章
 //删除二叉树中的最小值
    public E delMin(){
        Node ret=minimum(root);
        root=delMin(root);
        return ret.e;
    }
    private Node delMin(Node node){
        if (root==null)throw new IllegalArgumentException("the tree is empty!");
        if (node.left==null){
            Node reRight=node.right;
            node.right=null;
            return reRight;
        }
        else {
            node.left=delMin(node.left);
        }
        return node;
    }

    //删除二叉树中的最大值
    public E delMax(){
        Node ret=maximum(root);
        root=delMax(root);
        return ret.e;
    }
    private Node delMax(Node node){
        if (isEmpty())throw new IllegalArgumentException("the tree is empty!");
        if (node.right==null){
            Node reLeft=node.left;
            node.left=null;
            return reLeft;
        }
        else{
            node.right=delMax(node.right);
            return node;
        }


    }

    //删除二叉树中的元素e
    public void delElement(E e){
        root=delElement(root,e);
    }
    private Node delElement(Node node,E e){
        if (root==null)throw new IllegalArgumentException("the tree is empty!");
        if (e.compareTo(node.e)<0){
            node.left=delElement(node.left,e);
            return node;
        }
        else if (e.compareTo(node.e)>0){
            node.right=delElement(node.right,e);
            return node;
        }
        else {//e.compareTo(node.e==0)
            //如果待删除节点的左子树为空(左右子树都为空会在这种情况被处理掉)
            if(node.left==null){
                Node reRight=node.right; //用于返回的当前节点的右子树存入reRight中(是空的也没事);
                node.right=null;//释放node节点的空间
                size--;
                return reRight;
            }
            //如果待删除节点的右子树为空,情况与左子树为空相似
            if (node.right==null){
                Node reLeft=node.left;
                node.left=null;
                size--;
                return reLeft;
            }
            //当前节点的左右子树都不为空的情况
            Node successor=minimum(node.right);//能够用于继承当前节点位置的继承节点
            //Node successor=maxmum(node.left):可以有两种情况,以右子节点为根的树的最小值,或者以左子节点为根的树的最大值
            successor.left=node.left;
            successor.right=delMin(node.right);//此处的size已经自动-1了;
            node.left=null;
            node.right=null;
            return successor;
        }
    }

8.toString

    @Override
    public String toString(){
        StringBuilder res = new StringBuilder();
        generateBSTString(root, 0, res);
        return res.toString();
    }

    // 生成以node为根节点,深度为depth的描述二叉树的字符串
    private void generateBSTString(Node node, int depth, StringBuilder res){

        if(node == null){
            res.append(generateDepthString(depth) + "null\n");
            return;
        }

        res.append(generateDepthString(depth) + node.e +"\n");
        generateBSTString(node.left, depth + 1, res);
        generateBSTString(node.right, depth + 1, res);
    }

    private String generateDepthString(int depth){
        StringBuilder res = new StringBuilder();
        for(int i = 0 ; i < depth ; i ++)
            res.append("--");
        return res.toString();
    }
}

三:整体代码与测试函数

1.整体代码:

package IMUHERO;
import java.util.LinkedList;
import java.util.Stack;
import java.util.Queue;
public class BST <E extends Comparable<E>>{

    private class Node{
        public E e;
        public Node left;
        public Node right;
        public Node(E e){
            this.e=e;
            this.left=null;
            this.right=null;
        }
    }

    private Node root;
    private int size;
    public BST(){
        root=null;
        size=0;
    }
    //判断二叉树是否为空
    public boolean isEmpty(){
        return size==0;
    }
    //获得二叉树元素的个数
    public int getSize(){
        return size;
    }
    //在二叉树中添加元素(自动按照大小排序)
    public void add(E e){
        root=add(root,e);
    }
    private Node add(Node node,E e){
        if(node==null){
            size++;
            return new Node(e);
        }
        else if (e.compareTo(node.e)<0)node.left=add(node.left,e);//此处注意:要把当前节点的左边引用指向新增的节点
        else node.right=add(node.right,e);
        return node;
    }

    //判断二叉树中是否含有e
    public boolean contian(E e){
        return contain(root,e);
    }

    public boolean contain(Node node,E e){
        if (node==null)return false;
        else if (e.compareTo(node.e)<0)return contain(node.left,e);
        else if (e.compareTo(node.e)==0)return true;
        else return contain(node.right,e);
    }
    //前序遍历
    public void preOrder(){
        preOrder(root);
    }
    private void preOrder(Node node){
        if (node==null)return ;
            System.out.println(node.e);
            preOrder(node.left);
            preOrder(node.right);
    }
    //非递归算法
    public void preOrderNR(){

    if(root == null)
        return;

    Stack<Node> stack = new Stack<>();
    stack.push(root);
    while(!stack.isEmpty()){
        Node cur = stack.pop();
        System.out.println(cur.e);

        if(cur.right != null)
            stack.push(cur.right);
        if(cur.left != null)
            stack.push(cur.left);
    }
}
    //中序遍历
    public void inOrder(){
        inOrder(root);
    }
    private void inOrder(Node node){
        if (node==null)return;
        inOrder(node.left);
        System.out.println(node.e);
        inOrder(node.right);
    }
    //后序遍历
    public void  postOrder(){
        postOrder(root);
    }
    private void postOrder(Node node){
        if (node==null){
            return;
        }
        postOrder(node.left);
        postOrder(node.right);
        System.out.println(node.e);
    }
    //层序遍历
    public void levelOrder(){
        Queue <Node>lel=new LinkedList<>();
        if (root==null)return;
        lel.add(root);
        while (!lel.isEmpty()){
            Node cur=lel.remove();
            System.out.println(cur.e);
            if (cur.left!=null)lel.add(cur.left);
            if (cur.right!=null)lel.add(cur.right);
        }
    }

    // 寻找二分搜索树的最小元素
    public E minimum(){
        if(size == 0)
            throw new IllegalArgumentException("BST is empty");

        Node minNode = minimum(root);
        return minNode.e;
    }
    private Node minimum(Node node){
        if( node.left == null )
            return node;

        return minimum(node.left);
    }

    // 寻找二分搜索树的最大元素
    public E maximum(){
        if(size == 0)
            throw new IllegalArgumentException("BST is empty");

        return maximum(root).e;
    }
    private Node maximum(Node node){
        if( node.right == null )
            return node;

        return maximum(node.right);
    }

    //删除二叉树中的最小值
    public E delMin(){
        Node ret=minimum(root);
        root=delMin(root);
        return ret.e;
    }
    private Node delMin(Node node){
        if (root==null)throw new IllegalArgumentException("the tree is empty!");
        if (node.left==null){
            Node reRight=node.right;
            node.right=null;
            return reRight;
        }
        else {
            node.left=delMin(node.left);
        }
        return node;
    }

    //删除二叉树中的最大值
    public E delMax(){
        Node ret=maximum(root);
        root=delMax(root);
        return ret.e;
    }
    private Node delMax(Node node){
        if (isEmpty())throw new IllegalArgumentException("the tree is empty!");
        if (node.right==null){
            Node reLeft=node.left;
            node.left=null;
            return reLeft;
        }
        else{
            node.right=delMax(node.right);
            return node;
        }


    }

    //删除二叉树中的元素e
    public void delElement(E e){
        root=delElement(root,e);
    }
    private Node delElement(Node node,E e){
        if (root==null)throw new IllegalArgumentException("the tree is empty!");
        if (e.compareTo(node.e)<0){
            node.left=delElement(node.left,e);
            return node;
        }
        else if (e.compareTo(node.e)>0){
            node.right=delElement(node.right,e);
            return node;
        }
        else {//e.compareTo(node.e==0)
            //如果待删除节点的左子树为空(左右子树都为空会在这种情况被处理掉)
            if(node.left==null){
                Node reRight=node.right; //用于返回的当前节点的右子树存入reRight中(是空的也没事);
                node.right=null;//释放node节点的空间
                size--;
                return reRight;
            }
            //如果待删除节点的右子树为空,情况与左子树为空相似
            if (node.right==null){
                Node reLeft=node.left;
                node.left=null;
                size--;
                return reLeft;
            }
            //当前节点的左右子树都不为空的情况
            Node successor=minimum(node.right);//能够用于继承当前节点位置的继承节点
            //Node successor=maxmum(node.left):可以有两种情况,以右子节点为根的树的最小值,或者以左子节点为根的树的最大值
            successor.left=node.left;
            successor.right=delMin(node.right);//此处的size已经自动-1了;
            node.left=null;
            node.right=null;
            return successor;
        }
    }

}

2.测试函数

package IMUHERO;

public class Main {

    public static void main(String[] args) {
	// write your code here
        BST<Integer> bst = new BST<>();
        int[] nums = {5, 3, 6, 8, 4, 2};
        for(int num: nums)
            bst.add(num);
        System.out.println("_________前序遍历_____________");
        bst.preOrderNR();
        System.out.println("_________前序遍历非递归_______");
        bst.preOrderNR();
        System.out.println("_________后序遍历_____________");
        bst.postOrder();
        System.out.println("_________中序遍历_____________");
        bst.inOrder();
        System.out.println("_________层序遍历_____________");
        bst.levelOrder();
        System.out.println("_________删除最小值___________");
        System.out.println("删除的元素为:"+bst.delMin());
        System.out.println("剩余的元素为:");
        bst.inOrder();
        System.out.println("_________删除最大值___________");
        System.out.println("删除的元素为:"+ bst.delMax());
        System.out.println("剩余的元素为:");
        bst.inOrder();
        System.out.println("_________删除元素e___________");
        bst.delElement(4);
        System.out.println("剩余的元素为:");
        bst.inOrder();




    }
}

四:测试结果:

_________前序遍历_____________
5
3
2
4
6
8
_________前序遍历非递归_______
5
3
2
4
6
8
_________后序遍历_____________
2
4
3
8
6
5
_________中序遍历_____________
2
3
4
5
6
8
_________层序遍历_____________
5
3
6
2
4
8
_________删除最小值___________
删除的元素为:2
剩余的元素为:
3
4
5
6
8
_________删除最大值___________
删除的元素为:8
剩余的元素为:
3
4
5
6
_________删除元素e___________
剩余的元素为:
3
5
6

猜你喜欢

转载自blog.csdn.net/qq_37768971/article/details/88376363
今日推荐