由于在有序数组中插入数据项太慢,在链表中查找太慢,而树是兼有这两种性能的数据结构。
class treeNode {
public int iData;
public double dData;
public treeNode leftChild;
public treeNode rightChild;
public void displayNode() {
System.out.print("{");
System.out.print(iData);
System.out.print(",");
System.out.print(dData);
System.out.print("}");
}
}
public class tree {
private treeNode root;
public tree() {
root = null;
}
public treeNode find(int key) {
treeNode current = root;
while(current != null) {
if(current.iData == key) return current;
else if(current.iData > key) current = current.leftChild;
else current = current.rightChild;
}
return null;
}
public void insert(int id, double dd) {
treeNode newNode = new treeNode();
newNode.iData = id;
newNode.dData = dd;
if(root == null)
root = newNode;
else {
treeNode current = root;
treeNode parent = current;
while(true) {
if(current.iData > id) {
current = current.leftChild;
if(current == null) {
parent.leftChild = newNode;
return;
}
}
else if(current.iData < id) {
current = current.rightChild;
if(current == null) {
parent.rightChild = newNode;
return;
}
}
else return;
}
}
}
public void traverse(int traverseType) {
switch(traverseType) {
case 1:
System.out.println("PreOrder:");
preOrder(root);
break;
case 2:
System.out.println("InOrder:");
inOrder(root);
break;
case 3:
System.out.println("PostOrder:");
postOrder(root);
break;
default:
System.out.println("Initial.");
break;
}
}
//中序遍历,左子树-根节点-右子树
private void inOrder(treeNode localRoot) {
if(localRoot != null) {
inOrder(localRoot.leftChild);
System.out.print(localRoot.iData + " ");
inOrder(localRoot.rightChild);
}
}
//前序遍历,根节点-左子树-右子树
private void preOrder(treeNode localRoot) {
if(localRoot != null) {
System.out.print(localRoot.iData + " ");
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
//后序遍历,左子树-右子树-根节点
private void postOrder(treeNode localRoot) {
if(localRoot != null) {
postOrder(localRoot.leftChild);
postOrder(localRoot.rightChild);
System.out.print(localRoot.iData + " ");
}
}
public boolean delete(int key) {
treeNode current = root;
treeNode parent = root;
boolean isLeftChild = true;
while(current.iData != key) {
parent = current;
if(current.iData > key) {
isLeftChild = true;
current = current.leftChild;
}
else {
isLeftChild = false;
current = current.rightChild;
}
if(current == null) return false;
}
//删除的节点是叶子节点,可直接删除
if(current.leftChild == null && current.rightChild == null) {
if(current == root) {
root = null;
}
else if(isLeftChild) {
parent.leftChild = null;
}
else
parent.rightChild = null;
}
//删除的节点有左子节点,直接将左子节点上移
else if(current.rightChild == null) {
if(current == root)
root = current.leftChild;
else if(isLeftChild)
parent.leftChild = current.leftChild;
else
parent.rightChild = current.leftChild;
}
//删除的节点有右子节点,直接将右子节点上移
else if(current.leftChild == null) {
if(current == root)
root = current.rightChild;
else if(isLeftChild)
parent.leftChild = current.rightChild;
else
parent.rightChild = current.rightChild;
}
//删除的节点有左右两个子节点,让后继节点代替
else {
treeNode successor = getSuccessor(current);
if(current == root)
root = successor;
else if(isLeftChild)
parent.leftChild = successor;
else
parent.rightChild = successor;
successor.leftChild = current.leftChild;
}
return true;
}
private treeNode getSuccessor(treeNode delNode) {
treeNode successorParent = delNode;
treeNode successor = delNode;
treeNode 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;
}
public static void main(String[] args) {
tree t = new tree();
t.insert(50, 1.5);
t.insert(25, 1.2);
t.insert(75, 1.7);
t.find(50).displayNode();
t.traverse(2);
t.traverse(1);
t.traverse(3);
t.delete(75);
t.traverse(2);
}
}
还看到了两个概念:
满二叉树:除最后一层无任何子节点外,每一层上的所有结点都有两个子结点的二叉树。
完全二叉树:与满二叉树形态类似,但是最后一层并没有满。