二叉树的增、删、改、查(java实现)

package com.itheima;

/**
* 中序遍历是有序二叉树(不重复)
* 实现二叉树的增删改查
* @author Administrator
*
*/
public class MyTree {

private Node root;//根节点
//定义一个节点的内部类
private class Node{
    Node parent;//父节点
    Node left;//左儿子
    Node right;//右儿子
    Object data;//数据

    //构造方法
    public Node(Object data) {
        // TODO Auto-generated constructor stub
        this.data = data;
    }
}

/**
 * 1.添加数据
 * @param data
 */
public void add(Object data){
    //判断该数据是否存在,如果存在 返回
    if (contains(data)) {
        return;
    }
    //1.把数据放到根节点中
    Node node = new Node(data);
    //2.把节点链接到二叉树中,判断是否有根节点
    if (root == null) {
        //没有根节点
        root = node;
    } else {
        //有根节点
        //找位置,找父节点,比较与父节点的大小,大往右,小往左
        Node parent = findParent(data, root);
        //设置新增节点的父节点
        node.parent = parent;
        //开始比较
        if (compare(data, parent.data)) {
            //自己比父节点大
            parent.right = node;
        } else {
            //自己比父节点小
            parent.left = node;
        }
    }
}
/**
 * 二叉树中是否包含该数据
 * @param data
 * @return
 */
public boolean contains(Object data){

    return null != find(data);
}
/**
 * 
 * @param data 传递进来的数据
 * @param currentNode 当前的节点
 * @return  父节点
 */
private Node findParent(Object data, Node currentNode){
    //刚开始的时候,从根节点开始找
    Node temp = currentNode;
    Node parent = currentNode;

    // 循环查找
    while (temp != null) {
        parent = temp;
        //比较传递进来的数据与当前节点数据的大小(大往右,小往左)
        if (compare(data, temp.data)) {
            //大于往右
            temp = temp.right;
        } else {
            //小于往左
            temp = temp.left;
        }

    }
    return parent;

}

/**
 * 
 * @param o1
 * @param o2
 * @return  如果o1 > o2 返回ture。否则返回false
 */
public boolean compare(Object o1, Object o2){
    boolean res = false;
    //判断o1有没有实现比较器
    if (o1 instanceof Comparable) {
        //强制类型转换
        Comparable c1  = (Comparable) o1;
        Comparable c2  = (Comparable) o2;
        if (c1.compareTo(c2) > 0) {
            res = true;
        } else {
            //默认就是false
        }
    } else {
        //没有实现比较器
        res = o1.toString().compareTo(o2.toString()) > 0 ? true : false;
    }
    return res;
}

/**
 * 2.二叉树的查找
 * @param data
 * @return
 */
private Node find(Object data){
    //从根节点找
    Node temp = root;
    while (temp != null) {
        if (temp.data.equals(data) && temp.data.hashCode() == data.hashCode()) {
            //找打了
            break;
        } else if (compare(data, temp.data)) {
            //data > temp
            //往右找
            temp = temp.right;
        } else {
            //往左找
            temp = temp.left;
        }

    }
    return temp;
}

/**
 * 3.二叉树的删除(根据传入的数字进行删除)
 * @param data
 */
public void remove(Object data){
    //1.查找数据是否存在
    Node temp = find(data);
    //2.存在的话找到节点
    if (temp != null) {
        //3.删除节点
        //删除节点的时候分两种情况 根节点和非根节点

        //1.根节点
        if (temp == root) {
            //11.没有儿子
            if (temp.left == null && temp.right == null) {
                root = null;
            } else if (temp.right == null) {
                //12.只有一个左儿子
                root = root.left;
                root.parent = null;
            } else if (temp.left == null) {
                //13.只有一个右儿子
                root = root.right;
                root.parent = null;
            } else {
                //14.左右儿子都有
                //保留左儿子,右儿子跟随左儿子(就像古代的王位继承)
                Node left = getLeft(temp);
                root = left;//left成为新的根节点
                left.parent = null;
            }

        } else {
            //2.非根节点

            //21.没有儿子(叶子节点)
            if (temp.left == null && temp.right == null) {
                if (compare(temp.data, temp.parent.data)) {
                    //叶子节点在右边
                    temp.parent.right = null;
                } else {
                    //叶子节点在左边
                    temp.parent.left = null;
                }
            } else if (temp.right == null) {
                //22.只有一个左儿子
                if (compare(temp.data, temp.parent.data)) {
                    //在父节点的右边
                    temp.parent.right = temp.left;
                    temp.left.parent = temp.parent;
                } else {
                    //在父节点的左边
                    temp.parent.left = temp.left;
                    temp.left.parent = temp.parent;
                }

            } else if (temp.left == null) {
                //23.只有一个右儿子
                if (compare(temp.data, temp.parent.data)) {
                    // 在父节点的右边
                    temp.parent.right = temp.right;
                    temp.right.parent = temp.parent;
                } else {
                    //在父节点的左边
                    temp.parent.left = temp.right;
                    temp.right.parent = temp.parent;
                }
            } else {
                //24.左右儿子都有
                Node left = getLeft(temp);
                if (compare(left.data, temp.parent.data)) {
                    //比爷爷节点大
                    temp.parent.right = left;
                    left.parent = temp.parent;
                } else {
                    //比爷爷节点小
                    temp.parent.left = left;
                    left.parent = temp.parent;
                }


            }
        }

    }
}

/**
 * 
 * @param node 要删除的节点
 * @return  要删除节点的左儿子
 */
private Node getLeft(Node node){
    //保留左儿子,
    Node left = node.left;
    //处理右节点
    Node rightNewParrent = findParent(node.right.data, left);
    rightNewParrent.right = node.right;//把删除节点的右节点加在删除节点的左节点的最右边
    node.right.parent = rightNewParrent;
    return left;

}

/**
 * 4. 二叉树的修改
 * @param oldDara
 * @param newData
 */
public void update(Object oldDara, Object newData){
    //删除久的。添加新的
    remove(oldDara);
    add(newData);
}
/**
 * 递归打印
 */
public void print(){
    print(root);
}
/**
 * 方法重载
 * @param node
 */
public void print(Node node){
    if (node == null) {
        return;
    } else {
        print(node.left);
        System.out.println(node.data + ",");
        print(node.right);
    }

}

}

对二叉树的增删改查进行测试
package com.itheima;

/**
* 对二叉树进行测试
* @author Administrator
*
*/
public class TestMyTree {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    MyTree trees = new MyTree();
    int[] datas = {55,33,44,88,66,99};
    for (int i : datas) {
        //1.测试增加的方法
        trees.add(i);
    }

    //打印出二叉树
    trees.print();
    System.out.println();//换行的作用
    //2.测试查询的方法
    System.out.println(trees.contains(44));
    System.out.println();
    //3.测试删除
    trees.remove(99);
    trees.print();
    //4.测试更新
    System.out.println();

    trees.update(66, 77);
    trees.print();
}

}

你可能感兴趣的:(二叉树,遍历,增删改查)