和堆類似,二叉樹也是一種很奇特的數據結構。它包含了根節點,節點最多隻有一個左右節點。
父節點和左右子節點之間有一定的關係:
1. 父節點比左節點大(小)。
2. 父節點比右節點小(大)。
通過這種特性,二叉樹的查找定位非常方便,比數組、鏈表的查找效率要高很多。在我的機器上,從100萬個隨機整數中查找一個整數平均需要0.00386毫秒。可見效率確實很高。
不過,二次樹有一個致命的缺點:如果插入的數是經過排序的,則會使二次樹高度非常大,就等同於線性數組了,從而極大影響了查找和插入的效率。
下面是二叉樹的Java實現代碼。
- package cn.tenyears.demo;
- import java.util.Comparator;
- /**
- * Binary Tree
- *
- * @author taolue
- *
- */
- public class BinTree<T> {
- public class Node {
- private T data;
- private Node left;
- private Node right;
- public void setData(T data) {
- this.data = data;
- }
- public void setLeft(Node left) {
- this.left = left;
- }
- public void setRight(Node right) {
- this.right = right;
- }
- public Node getLeft() {
- return this.left;
- }
- public Node getRight() {
- return this.right;
- }
- public T getData() {
- return this.data;
- }
- public Node(T data, Node l, Node r) {
- this.data = data;
- this.left = l;
- this.right = r;
- }
- }
- class ParentAndChild {
- public Node parent = null;
- public Node child = null;
- public ParentAndChild(Node p, Node c) {
- this.parent = p;
- this.child = c;
- }
- }
- private Comparator<T> comparator = null;;
- public final ParentAndChild NONE_PC = new ParentAndChild(null, null);
- private Node root = null;
- private int treeSize = 0;
- public BinTree(Comparator<T> comparator) {
- this.comparator = comparator;
- }
- public Node search(T data) {
- return searchPC(data).child;
- }
- public void insert(T data) {
- Node temp = root;
- Node parent = null;
- int equal = 0;
- while (temp != null) {
- parent = temp;
- equal = comparator.compare(data, temp.getData());
- if (equal < 0)
- temp = temp.getLeft();
- else
- temp = temp.getRight();
- }
- Node one = new Node(data, null, null);
- if (parent == null)
- root = one;
- else if (comparator.compare(data, parent.getData()) < 0)
- parent.setLeft(one);
- else
- parent.setRight(one);
- this.treeSize++;
- }
- public boolean delete(T data) {
- Node deleted = null;
- Node parent = null;
- Node right = null;
- ParentAndChild pc = this.searchPC(data);
- deleted = pc.child;
- parent = pc.parent;
- if (deleted == null)
- return false;
- if (deleted.getRight() == null)
- right = deleted.getLeft();
- else if (deleted.getLeft() == null)
- right = deleted.getRight();
- else {
- Node parent1 = deleted;
- right = deleted.getLeft();
- while (right.getRight() != null) {
- parent1 = right;
- right = right.getRight();
- }
- if (parent1 == deleted)
- right.setRight(deleted.getRight());
- else {
- parent1.setRight(right.getLeft());
- right.setLeft(deleted.getLeft());
- right.setRight(deleted.getRight());
- }
- }
- if (parent == null)
- root = right;
- else if (comparator.compare(deleted.getData(), parent.getData()) < 0)
- parent.setLeft(right);
- else
- parent.setRight(right);
- this.treeSize--;
- return true;
- }
- public int getSize() {
- return this.treeSize;
- }
- private ParentAndChild searchPC(T data) {
- Node temp = root;
- Node parent = null;
- int equal = 0;
- while (temp != null) {
- equal = comparator.compare(data, temp.getData());
- if (equal == 0)
- break;
- else {
- parent = temp;
- if (equal < 0)
- temp = parent.getLeft();
- else
- temp = parent.getRight();
- }
- }
- if (temp != null)
- return new ParentAndChild(parent, temp);
- return this.NONE_PC;
- }
- public static void main(String[] args) {
- Comparator<Integer> com = new Comparator<Integer>() {
- public int compare(Integer o1, Integer o2) {
- return o1.compareTo(o2);
- }
- };
- BinTree<Integer> tree = new BinTree<Integer>(com);
- int size = 1000000;
- Integer[] a = new Integer[size];
- for (int i = 0; i < size; i++) {
- a[i] = Integer.valueOf((int) Math.round(Math.random() * size));
- tree.insert(a[i]);
- }
- long start = System.currentTimeMillis();
- // find
- for (int i = 0; i < size; i++) {
- if (tree.search(a[i]) == null)
- System.out.println("Error: Find None.");
- }
- long end = System.currentTimeMillis();
- System.out.println("Last(AVG): " + (end - start) * 1.0f / size + " ms");
- }
- }