共有三个类:
结构体:Object(仅存放数据)
树类:Tree
测试类:Test
Object:
package 二叉树;
public class Object {
public int value;
}
Tree:
package 二叉树;
public class Tree {
public Node root; //根节点
//public Node left; //指向左孩子节点的引用
//public Node right; //指向右孩子节点的引用
public Tree(){
root=null;
}
//
public boolean isEmpty(){
if(root==null){
return true;
}
return false;
}
//递归创建二叉树
Node Root;
public void addTree(Object obj){
if(isEmpty()){
root=new Node(obj);
System.out.println("root:"+root.data.value);
root.leftChild=null;
root.rightChild=null;
Root=root;
}else{
if(obj.value<Root.data.value){
if(Root.getLeftChild()!=null){
if(Root.getLeftChild().data.value==obj.value){
System.out.println("已存在"+Root.data.value+"请换值添加");
}else{
Root=Root.getLeftChild();
System.out.println("root:"+Root.data.value);
addTree(obj);
}
}else{
Root.setLeftChild(new Node(obj));
System.out.println("左 :"+Root.getLeftChild().data.value);
Root=root;
}
}else if(obj.value>Root.data.value){
if(Root.getRightChild()!=null){
if(Root.getRightChild().data.value==obj.hashCode()){
System.out.println("已存在"+Root.data.value+"请换值添加");
}else{
Root=Root.getRightChild();
System.out.println("root:"+Root.data.value);
addTree(obj);
}
}else{
Root.setRightChild(new Node(obj));
System.out.println("右 :"+Root.getRightChild().data.value);
Root=root;
}
}else{
System.out.println("已存在"+Root.data.value+"请换值添加");
}
}
}
//普通方式创建二叉树
public void addTreeNode(Object obj){
Node node = new Node(obj);
Node temp;
Node left;
Node right;
if(isEmpty()){
root=node;
System.out.println("root:"+root.data.value);
root.leftChild=null;
root.rightChild=null;
}else{
temp = root;
while(true){ //temp.leftChild!=null||temp.rightChild!=null
if(node.data.value<temp.data.value){ //左
if(temp.leftChild!=null){
left = temp.getLeftChild();
if(node.data.value==left.data.value){
System.out.println("已存在"+node.data.value+"请换值添加");
break;
}
temp = left;
System.out.println("root:"+temp.data.value);
}else{
temp.setLeftChild(node);
System.out.println("左 :"+temp.getLeftChild().data.value);
break;
}
}else if(node.data.value>temp.data.value){ //右
if(temp.rightChild!=null){
right = temp.getRightChild();
if(node.data.value==right.data.value){
System.out.println("已存在"+node.data.value+"请换值添加");
break;
}
temp=right;
System.out.println("root:"+temp.data.value);
}else{
temp.setRightChild(node);
System.out.println("右 :"+temp.getRightChild().data.value);
break;
}
}else{
System.out.println("已存在"+node.data.value+"请换值添加");
break;
}
}
}
}
//二叉树的遍历:先序遍历
public void preOrder(Node temp){
if(temp!=null){
System.out.println("--先序--"+temp.data.value);
preOrder(temp.getLeftChild());
preOrder(temp.getRightChild());
}
}
//二叉树的:中序遍历
public void inOrder(Node temp){
if(temp!=null){
inOrder(temp.getLeftChild());
System.out.println("--中序--"+temp.data.value);
inOrder(temp.getRightChild());
}
}
//二叉树的:后序遍历
public void postOrder(Node temp){
if(temp!=null){
postOrder(temp.getLeftChild());
postOrder(temp.getRightChild());
System.out.println("--后序--"+temp.data.value);
}
}
//求二叉树的层数
public int hight(Node node){
if(node==null){
return 0;
}else{
int i=hight(node.getLeftChild());
int j=hight(node.getRightChild());
return (i<j)?(j+1):(i+1);
}
}
//求二叉树的节点数
public int sumNode(Node node){
if(node==null){
return 0;
}else{
int a=sumNode(node.getLeftChild());
int b=sumNode(node.getRightChild());
return 1+a+b;
}
}
//求二叉树中一个节点的父节点,双亲结点
public Node parent(Object obj){
Node temp=parent(root, obj);
return temp;
}
public Node parent(Node node, Object findnode){
if(node==null){
return null;
}
if((node.getLeftChild()!=null&&node.getLeftChild().data.value==findnode.value)||(node.getRightChild()!=null&&node.getRightChild().data.value==findnode.value)){
//如果找到返回双亲节点
//这里需要判断node的左或右孩子是否为空的条件,否则一旦node的左孩子或右孩子为空(即:找不到)会报空指针的错误
return node;
}
//在左子树中查找 , 如果左子树中没有去右子树中查找
Node N;
if((N=parent(node.getLeftChild(),findnode))!=null){
return N;
}else{
return parent(node.getRightChild(),findnode);
}
}
//查找节点
public Node findNode(Object obj){
Node node = new Node(obj);
if(root==null){
System.out.println("树中没有你要查找的值!");
return null;
}else{
Node temp=findNode(root,node);
return temp;
}
}
public Node findNode(Node roo,Node node){
if(roo==null){
return null;
}
if(roo.data.value==node.data.value){
return roo;
}
Node N;
Node P;
if((N=findNode(roo.getLeftChild(),node))!=null){
return N;
}else{
roo=roo.getRightChild();
if((P=findNode(roo,node))==null){
return null;
}else{
return P;
}
}
}
//删除树中的一个节点,用被删除节点的孩子补上,不能破坏二叉树的排序规律:左孩子始终小于右孩子
public void delSort(Object obj){
Node temp;
Node node=parent(obj);
if((temp=findNode(obj))!=null){
//如果删除的是根节点,就让其左子树的最大值放在根节点
if(root.data.value==temp.data.value){
Node node1=delFind(temp.getLeftChild());
node1.setLeftChild(root.getLeftChild().getLeftChild());
node1.setRightChild(root.getRightChild());
root=node1;
}else{
if(temp.getLeftChild()==null&&temp.getRightChild()==null){
//如果要删除的节点没有左和右孩子,则找到被删除节点的父节点,让其父节点的左孩子指向或右孩子指向置空,即删除
if(node.data.value<obj.value){//要删除节点是父节点的右孩子
node.setRightChild(null);//置空删除右孩子
}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
node.setLeftChild(null);//置空删除
}
}else if(temp.getLeftChild()!=null&&temp.getRightChild()!=null){
/*
* 若左右孩子都不为空,则从要删除节点的右子树上取最小值放到被删除节点上即可,并把右子树上的最小值删除
* Q
* /
* E
* / \
* A F
* / \
* D B
* /
* C
* 此时若删除E,则首先找到E的父节点Q和E的所有子孙中的最大节点B,
* 然后让Q指向B,B的左孩子指向A,B的右孩子指向F,最后把E置空释放空间;
*
* Q
* /
* B
* / \
* A F
* / \
* D C
* E=null 释放掉
*
*
*/
Node node1=delFind(temp.getLeftChild());
if(node.data.value<obj.value){//要删除节点是父节点的右孩子
//取被删除节点的左孩子中的最大值,让父节点的右孩子指向被删除节点的左孩子中的最大值;若被删除节点的左孩子中的最大值等于被删除节点的左孩子的值 则让父节点的右孩子指向被删除节点的左孩子
if(temp.getLeftChild().data.value==node1.data.value){
node.setRightChild(temp.getLeftChild());
temp.getLeftChild().setRightChild(temp.getRightChild());
temp=null;
}else{
node.setRightChild(node1);
node1.setLeftChild(temp.getLeftChild());
node1.setRightChild(temp.getRightChild());
temp=null;
}
}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
if(temp.getLeftChild().data.value==node1.data.value){
node.setLeftChild(temp.getLeftChild());
temp.getLeftChild().setRightChild(temp.getRightChild());
temp=null;
}else{
node.setLeftChild(node1);
node1.setLeftChild(temp.getLeftChild());
node1.setRightChild(temp.getRightChild());
temp=null;
}
}
}else if(temp.getLeftChild()!=null&&temp.getRightChild()==null){//左孩子不为空右孩子为空的情况,则把要删除节点的左孩子放到被删除节点上即可
if(node.data.value<obj.value){//要删除节点是父节点的右孩子
node.setRightChild(temp.getLeftChild());//要删除节点的父节点的右孩子指向为被删除节点的左孩子,并把被删除节点的左指向置空,即删除
temp=null;
}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
node.setLeftChild(temp.getLeftChild());
temp=null;
}
}else if(temp.getLeftChild()==null&&temp.getRightChild()!=null){
//左孩子为空右孩子不为空的情况,则把要删除节点的右孩子放到被删除节点上即可
if(node.data.value<obj.value){//要删除节点是父节点的右孩子
node.setRightChild(temp.getRightChild());//要删除节点的父节点的右孩子指向为被删除节点的左孩子,并把被删除节点的左指向置空,即删除
temp=null;//删除之后置空,释放空间
}else if(node.data.value>obj.value){//要删除节点是父节点的左孩子
node.setLeftChild(temp.getRightChild());
temp=null;
}
}
}
}else{
System.out.println("你需要删除的节点不存在!");
//return false;
}
}
//查找一个节点下所有子孙中的最大值,并且删除这个节点,
public Node delFind(Node node){ //传入参数为被删除节点的左孩子Node node
//Node temp=node;
if(node.getRightChild()==null){
return node;
}
if(node.getRightChild().getRightChild()==null){
if(node.getRightChild().getLeftChild()!=null){
/*
* 如果被删除的节点有有左孩子,需要用被删除节点的父节点的右孩子指向被删除结点的左孩子,
* 然后再把被删除节点的左孩子指向设为null,那么需要删除的节点就被删掉了
* 意思就是把B删除,把A指向C
* A
* / \
* D B
* /
* C
*/
Node temp=node.getRightChild();
node.setRightChild(node.getRightChild().getLeftChild());
//node.getRightChild().setLeftChild(null);
temp.setLeftChild(null);
return temp;
}
Node temp=node.getRightChild();
node.setRightChild(null);
return temp;
}
return delFind(node.getRightChild());
}
//获取右子树中的最小节点
public Node minRightNode(Node node){//传入参数为被删除节点的右孩子Node node
if(node.getLeftChild()==null){
return null;
}
if(node.getLeftChild().getLeftChild()==null){
if(node.getLeftChild().getRightChild()!=null){
/*
* 如果被删除的节点有右孩子,需要用被删除节点的父节点的左孩子指向被删除结点的右孩子,
* 然后再把被删除节点的右孩子指向设为null,那么需要删除的节点就被删掉了
* 意思就是把 D 删除,把A指向C
* A
* / \
* D B
* \
* C
*/
Node temp=node.getLeftChild();
node.setLeftChild(node.getLeftChild().getRightChild());
//node.getRightChild().setLeftChild(null);
temp.setRightChild(null);
return temp;
}
Node temp=node.getLeftChild();
node.setLeftChild(null);
return temp;
}
return minRightNode(node.getLeftChild());
}
class Node {
public Object data; //数据区 节点存储的值
public Node leftChild; //指向左孩子节点的引用
public Node rightChild; //指向右孩子节点的引用
public Node(Object value){
this.data=value;
leftChild = null;
rightChild = null;
}
public Node(){
}
public void setData(Object data){
this.data=data;
}
public Object getData(){
return data;
}
public void setLeftChild(Node node){
this.leftChild=node;
}
public Node getLeftChild(){
return leftChild;
}
public void setRightChild(Node node){
this.rightChild=node;
}
public Node getRightChild(){
return rightChild;
}
}
}
测试类:Test
package 二叉树;
public class Test {
public static void main(String[] args){
Tree tree = new Tree();
Object[] obj = new Object[5];
Object a= new Object();
a.value=10;
Object a1= new Object();
a1.value=8;
Object a2= new Object();
a2.value=5;
Object a3= new Object();
a3.value=4;
Object a4= new Object();
a4.value=6;
Object a5= new Object();
a5.value=7;
Object a6= new Object();
a6.value=9;
Object a7= new Object();
a7.value=11;
Object a12= new Object();
a12.value=12;
tree.addTree(a);
tree.addTree(a1);
tree.addTree(a2);
tree.addTree(a3);
tree.addTree(a4);
tree.addTree(a5);
tree.addTree(a6);
tree.addTree(a7);
System.out.println("--------先序--------");
tree.preOrder(tree.root);
System.out.println("--------中序--------");
tree.inOrder(tree.root);
System.out.println("--------后序--------");
tree.postOrder(tree.root);
System.out.println("树的高度:"+tree.hight(tree.root));
System.out.println("树的节点总数:"+tree.sumNode(tree.root));
System.out.println("寻找一个节点的双亲节点:"+tree.parent(tree.root, a4).data.value);
if(tree.findNode(a7)==null){
System.out.println("树中没有你要查找的值!");
}else{
System.out.println("查找到一个节点:"+a7.value);
}
System.out.println("-----删除节点-----");
tree.delSort(a1);
tree.preOrder(tree.root);
}
}
/* 普通法添加节点
tree.addTreeNode(a);
tree.addTreeNode(a1);
tree.addTreeNode(a2);
tree.addTreeNode(a3);
tree.addTreeNode(a5);
tree.addTreeNode(a6);
tree.addTreeNode(a4);*/<pre name="code" class="java">/*测试结果:
测试结果:
root:10
左 :8
root:8
左 :5
root:8
root:5
左 :4
root:8
root:5
右 :6
root:8
root:5
root:6
右 :7
root:8
右 :9
右 :11
--------先序--------
--先序--10
--先序--8
--先序--5
--先序--4
--先序--6
--先序--7
--先序--9
--先序--11
--------中序--------
--中序--4
--中序--5
--中序--6
--中序--7
--中序--8
--中序--9
--中序--10
--中序--11
--------后序--------
--后序--4
--后序--7
--后序--6
--后序--5
--后序--9
--后序--8
--后序--11
--后序--10
树的高度:5
树的节点总数:8
寻找一个节点的双亲节点:5
查找到一个节点:11
-----删除节点-----
--先序--10
--先序--7
--先序--5
--先序--4
--先序--6
--先序--9
--先序--11
*/