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

来源:互联网 发布:mybatis 多个数据库 编辑:程序博客网 时间:2024/05/01 23:30

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();}

}

0 0