您的位置:首页 > 编程语言 > Java开发

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

2016-02-16 15:37 225 查看
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();
}


}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: