定义一个类,用来当做二叉树的节点,也可以用内部类
package dateStructure;
public class TNode {
public int date;
public TNode leftChild;
public TNode rightChild;
public TNode(int key) {
this.date = key;
}
}
下面是二叉树的实现:比较难的是删除,仔细琢磨。
package dateStructure;
public class IThree {
TNode root = null;
/**
* 查找节点
*
* 查找节点的时间取决于这个节点所在的层数, 每一层最多有2n-1个节点,总共N层共有2n-1个节点, 那么时间复杂度为O(logN),底数为2,
* N表示的是二叉树节点的总数,而不是层数
*
* @param key
* @return
*/
public TNode find(int key) {
TNode temp = root;
while (temp != null) {
if (key > temp.date) {
temp = temp.rightChild;
} else if (key < temp.date) {
temp = temp.leftChild;
} else {
return temp;
}
}
return null;
}
/**
* 插入新节点
*
* 要插入节点,必须先找到插入的位置。 与查找操作相似,由于二叉搜索树的特殊性, 待插入的节点也需要从根节点开始进行比较,
* 小于根节点则与根节点左子树比较,反之则与右子树比较, 直到左子树为空或右子树为空,则插入到相应为空的位置, 在比较的过程中要注意保存父节点的信息 及
* 待插入的位置是父节点的左子树还是右子树,才能插入到正确的位置。
*
* @param key
* @return
*/
public boolean insert(int key) {
TNode newNode = new TNode(key);
if (root == null) {
root = newNode;
return true;
}
TNode preNode = null;
TNode temp = root;
while (temp != null) {
preNode = temp;
if (key > temp.date) {
temp = temp.rightChild;
if (temp == null) {
preNode.rightChild = newNode;
return true;
}
} else {
temp = temp.leftChild;
if (temp == null) {
preNode.leftChild = newNode;
return true;
}
}
}
return false;
}
/**
* 遍历二叉树
*
* @param key
* @return
*/
// 先序遍历
public void infixOrder(TNode current) {
if (current != null) {
System.out.print(current.date + " ");
infixOrder(current.leftChild);
infixOrder(current.rightChild);
}
}
// 中序遍历
public void preOrder(TNode current) {
if (current != null) {
preOrder(current.leftChild);
System.out.print(current.date + " ");
preOrder(current.rightChild);
}
}
// 后序遍历
public void postOrder(TNode current) {
if (current != null) {
postOrder(current.leftChild);
postOrder(current.rightChild);
System.out.print(current.date + " ");
}
}
/**
* 查找最值
*
* 要找最小值,先找根的左节点, 然后一直找这个左节点的左节点, 直到找到没有左节点的节点,那么这个节点就是最小值。 同理要找最大值,一直找根节点的右节点,
* 直到没有右节点,则就是最大值
*
* @return
*/
// 查找最大值
public TNode findMax() {
TNode preNode = null;
TNode temp = root;
if (root != null) {
while (temp != null) {
preNode = temp;
temp = temp.rightChild;
}
}
return preNode;
}
// 查找最小值
public TNode findMin() {
TNode preNode = null;
TNode temp = root;
if (root != null) {
while (temp != null) {
preNode = temp;
temp = temp.leftChild;
}
}
return preNode;
}
/**
* 删除节点 删除节点是二叉搜索树中最复杂的操作,
* 删除的节点有三种情况,前两种比较简单,但是第三种却很复杂。
* 1、该节点是叶节点(没有子节点)
* 2、该节点有一个子节点
* 3、该节点有两个子节点
*/
public boolean delete(int key) {
TNode preNode = root;
TNode nextNode = root;
while (nextNode.date != key) {
preNode = nextNode;
if (key < nextNode.date) {
nextNode = nextNode.leftChild;
} else {
nextNode = nextNode.rightChild;
}
if (nextNode == null) {
return false;
}
}
//该节点是叶子结点
if (nextNode.leftChild == null && nextNode.rightChild == null) {
// 如果该叶子结点是根节点
if (nextNode == root)
root = null;
// 不是根结点
if (preNode.leftChild == nextNode) {
preNode.leftChild = null;
} else {
preNode.rightChild = null;
}
return true;
//该节点只有右结点
}else if (nextNode.leftChild == null && nextNode.rightChild != null) {
if(nextNode == root)
root = nextNode.rightChild;
if(preNode.rightChild == nextNode) {
preNode.rightChild = nextNode.rightChild;
}else {
preNode.leftChild = nextNode.rightChild;
}
return true;
//该节点只有左节点
}else if(nextNode.leftChild != null && nextNode.rightChild == null) {
if(nextNode == root)
root = nextNode.leftChild;
if(preNode.rightChild == nextNode) {
preNode.rightChild = nextNode.leftChild;
}else {
preNode.leftChild = nextNode.leftChild;
}
return true;
//该节点有两个子节点
}else {
TNode successor = getSuccessor(nextNode);
if(nextNode == root)
root = successor;
if(preNode.leftChild == nextNode) {
preNode.leftChild = successor;
}else {
preNode.rightChild = successor;
}
successor.leftChild = nextNode.leftChild;
return true;
}
}
//找到删除节点的中序后继元素
public TNode getSuccessor(TNode delNode){
TNode successorParent = delNode;
TNode successor = delNode;
TNode current = delNode.rightChild;
while(current != null){
successorParent = successor;
successor = current;
current = current.leftChild;
}
//后继节点不是删除节点的右子节点,将后继节点替换删除节点
if(successor != delNode.rightChild){
successorParent.leftChild = successor.rightChild;
successor.rightChild = delNode.rightChild;
}
return successor;
}
// Other Method......
public static void main(String[] args) {
IThree th = new IThree();
th.insert(4);
th.insert(2);
th.insert(1);
th.insert(3);
th.insert(6);
th.insert(5);
th.insert(7);
th.insert(8);
th.insert(0);
System.out.println(th.find(3).date);
System.out.print("先序遍历:");
th.infixOrder(th.root);
System.out.println();
System.out.print("中序遍历:");
th.preOrder(th.root);
System.out.println();
System.out.print("后序遍历:");
th.postOrder(th.root);
System.out.println();
System.out.println("最大值:" + th.findMax().date);
System.out.println("最小值:" + th.findMin().date);
System.out.println(th.delete(6));
System.out.print("中序遍历:");
th.preOrder(th.root);
System.out.println();
}
}