二叉树是指一个节点上最对有两个子节点,分别称为左子节点和右子节点。
二叉搜索树(Binary Search Tree)是指一种特殊的二叉树,但其拥有一种特性,即一个节点的左子树上所有节点中的关键值均小于这个节点;而右子树上的所有节点中的关键值总是大于等于这个节点。又称为二叉查找树或二叉排序树。
/**
* 二叉搜索树
*/
package com.eight;
import java.util.Stack;
public class TreeAPP {
publicstatic void main(String[] args) {
Tree theTree = new Tree();
theTree.insert(50);
theTree.insert(25);
theTree.insert(75);
theTree.insert(12);
theTree.insert(37);
theTree.insert(43);
theTree.insert(30);
theTree.insert(33);
theTree.insert(87);
theTree.insert(93);
theTree.insert(97);
theTree.traverse(1);
theTree.traverse(2);
theTree.traverse(3);
theTree.display();
intvalue=99;
Node found = theTree.find(value);
if(found != null) {
System.out.println("找到了" );
}else
System.out.println("没找到"+value);
intvalue2=97;
Node found2 = theTree.find(value2);
if(found2 != null) {
System.out.println("找到了" );
}else
System.out.println("没找到"+value2);
//theTree.delete(11);theTree.display();
theTree.delete(97);theTree.display();
theTree.delete(30);theTree.display();
theTree.delete(25);theTree.display();
booleandidDelete = theTree.delete(11);
if(didDelete)
System.out.println("删除成功");
else
System.out.println("该树中没有这个数");
}
}
//结点类:采用二叉链表存储结构
class Node
{
publicObject data;
publicNode leftChild;
publicNode rightChild;
publicNode(Object data,Node leftChild,Node rightChild)
{
this.data= data;
this.leftChild= leftChild;
this.rightChild= rightChild;
}
publicNode(Object data)
{
this(data,null,null);
}
publicNode()
{
this(null);
}
}
//树
class Tree
{
privateNode root;
publicTree()
{
root= null;
}
//增
publicvoid insert(Object value)
{
Nodenewnode = new Node(value);
if(root== null)//如果是空树
{
root= newnode;
}else{
Nodenode = root;
Nodeparent = null;
while(true)
{
parent= node;
if((int)value<(int)node.data)//如果要插入的比节点小
{
node= node.leftChild;
if(node==null)
{
parent.leftChild= newnode;
return;
}
}else{//如果要插入的比节点大或者等于节点的关键值
node= node.rightChild;
if(node==null)
{
parent.rightChild= newnode;
return;
}
}
}
}
}
//删
publicboolean delete(Object value)
{
Nodeparent = root;
Nodenode = root;
booleanisLeft = true;
//先找到要删除的这个节点
while(!node.data.equals(value))//报错java.lang.NullPointerException
{
parent = node;
if((int)value<(int)node.data)
{
isLeft= true;
node= node.leftChild;
}else{
isLeft= false;
node= node.rightChild;
}
if(node==null){
//System.out.println("待删节点不存在");
returnfalse;
}//找到最后的node就是待删节点
}
//如果待删节点是叶子节点
if(node.rightChild==null&& node.leftChild==null)
{
if(node==root)//如果只有根节点
root=null;
elseif(isLeft)
{
parent.leftChild= null;
}else{
parent.rightChild= null;
}
}
//如果待删结点只有一个子节点
elseif(node.rightChild==null){//如果待删结点只有左子节点
if(node==root)
root= node.leftChild;
elseif(isLeft){
parent.leftChild= node.leftChild;
}else{
parent.rightChild= node.leftChild;
}
}
elseif(node.leftChild==null){//如果待删结点只有右子节点
if(node==root){
root= node.rightChild;
}elseif(isLeft){
parent.leftChild= node.rightChild;
}else{
parent.rightChild= node.rightChild;
}
}
//如果待删结点有两个子节点
else{
//先找到后继结点
Nodesuccessor = getSuccessor(node);
if(node==root){
root= successor;
}elseif(isLeft){
parent.leftChild= successor;
}else{
parent.rightChild= successor;
}
successor.leftChild= node.leftChild;
}
returntrue;
}
//找到后继结点
publicNode getSuccessor(Node delnode){
NodesuccessorParent = delnode;
Nodesuccessor = delnode;
Nodecurrent = delnode.rightChild;//得到待删除节点的右子节点
while(current!=null){//如果待删节点有右子节点的话,找到该右子节点的最左子孙
successorParent= successor;
successor= current;
current= current.leftChild;
}
//如果后继结点不是待删结点的右子节点,而是右子节点的左后代
if(current!=delnode.rightChild){
successorParent.leftChild= successor.rightChild;
successor.rightChild= delnode.rightChild;
}
returnsuccessor;
}
//找
publicNode find(Object value)
{
Nodenode = root;
while(!node.data.equals(value))
{
if((int)value<(int)node.data)
{
node= node.leftChild;
}else{
node= node.rightChild;
}
if(node== null)
{
returnnull;
}
}
returnnode;
}
//前序遍历:根节点-其左子树-其右子树
publicvoid preOrder(Node node)
{
if(node!=null)
{
System.out.print(node.data+"");
preOrder(node.leftChild);
preOrder(node.rightChild);
}
}
//中序遍历:其左子树-根节点-其右子树
publicvoid inOrder(Node node)
{
if(node!=null)
{
inOrder(node.leftChild);
System.out.print(node.data+"");
inOrder(node.rightChild);
}
}
//后序遍历:其左子树-其右子树-根节点
publicvoid postOrder(Node node)
{
if(node!=null)
{
postOrder(node.leftChild);
postOrder(node.rightChild);
System.out.print(node.data+"");
}
}
publicvoid traverse(int traverseType)
{
switch(traverseType) {
case1:
System.out.print("\nPreordertraversal: ");
preOrder(root);
break;
case2:
System.out.print("\nInordertraversal: ");
inOrder(root);
break;
case3:
System.out.print("\nPostordertraversal: ");
postOrder(root);
break;
}
System.out.println();
}
//遍历
publicvoid display(){
Stackstack1 = new Stack();//java.util.Stack中的栈是用数组实现的,利用数组实现的栈方便显示树的形状
stack1.push(root);//把跟入栈
intnBlanks = 32;
booleanisRowEmpty = false;
System.out.println("......................................................................");
while(isRowEmpty == false) {
Stackstack2 = new Stack();
isRowEmpty= true;
for (int j = 0; j < nBlanks; j++)
System.out.print('');
while (!stack1.isEmpty() ) {
Nodetemp = (Node) stack1.pop();
if(temp != null) {
System.out.print(temp.data);
stack2.push(temp.leftChild);
stack2.push(temp.rightChild);
if(temp.leftChild != null || temp.rightChild != null)
isRowEmpty= false;
}else {
System.out.print("--");
stack2.push(null);
stack2.push(null);
}
for(int j = 0; j < nBlanks * 2 - 2; j++)
System.out.print('');
}
System.out.println();
nBlanks/= 2;
while(stack2.isEmpty() == false)
stack1.push(stack2.pop());
}
System.out.println(".....................................................................");
}
}
结果是:Preorder traversal: 50 25 12 37 30 33 43 75 87 93 97
Inorder traversal: 12 25 30 33 37 43 50 75 87 93 97
Postorder traversal: 12 33 30 43 37 25 97 93 87 75 50
......................................................
50
25 75
12 37 -- 87
-- -- 30 43 -- -- -- 93
-- -- -- -- -- 33 -- -- -- -- -- -- -- -- -- 97
................................................................
该树中没有这个数