二叉树的增、删、改、查(java实现)
2016-02-16 15:37
225 查看
package com.itheima;
/**
* 中序遍历是有序二叉树(不重复)
* 实现二叉树的增删改查
* @author Administrator
*
*/
public class MyTree {
}
对二叉树的增删改查进行测试
package com.itheima;
/**
* 对二叉树进行测试
* @author Administrator
*
*/
public class TestMyTree {
}
/**
* 中序遍历是有序二叉树(不重复)
* 实现二叉树的增删改查
* @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(); }
}
相关文章推荐
- java的xpath语法
- Java正则表达式详解
- java常用算法之最长回文子串(Longest Palindromic Substring)
- 通过Junit和Spring-Test测试SpringMVC的web应用
- Java注解全面解析
- Java并发编程:Lock
- Spring源码学习之BeanFactory体系结构
- Java Socket超时浅析
- Eclipse中Build Workspace 优化
- Java正则表达式
- Eclipse颜色主题插件:Eclipse Color Theme
- Java常用工具类
- Java-强引用、软引用、弱引用、虚引用详解
- java web点击链接用js判断用户是否已经登录 (js获取session及判断是否为空)
- Java基础高级二(多线程)
- Java基础——数组应用之字符串String类
- eclipse 插件编写(一)
- Maven学习 (三) 使用m2eclipse创建web项目
- FusionCharts的使用总结(java)
- java 单例模式及getInstance的好处