距离上次使用二叉树快有一年的时间了,是时候重温一次了。
【二叉树的定义】
二叉树是层次结构,要么是空集,要么是由一个成为根的元素和两颗不同的子二叉树组成(递归定义,子二叉树也可能是空集)。
两个子二叉树分别称为左子树和右子树。一个节点的左子树的根节点称为该节点的左孩子,没有孩子的点称为叶节点。
二叉查找树的特点是,每一个节点左子树中节点的值都小于该节点的值,右子树中节点的值都大于该点。
下面是节点的数据结构:
1 /** 2 * Created by Solare on 15/7/6. 3 */ 4 public class TreeNode { 5 Object element; 6 TreeNode left; 7 TreeNode right; 8 9 public TreeNode(Object o) { 10 element = o; 11 } 12 }
【插入算法】
如果二叉树是空的,则使用新元素创建一个根节点;否则,为新元素寻找父节点。如果新元素的值小于父节点的值,则将新元素的节点设置为父节点的左孩子;否则将其设为右孩子。
这里使用了递归的方式,二叉树类的代码如下:
1 /** 2 * Created by Solare on 2015/7/6. 3 */ 4 //My BinaryTree 5 public class BinaryTree { 6 private TreeNode root; 7 private int size = 0; 8 9 /** Create a default binary tree */ 10 public BinaryTree() { 11 ; 12 } 13 14 /** Create a binary tree from an array of objects */ 15 public BinaryTree(Object[] objects) { 16 for (int i = 0; i < objects.length; i ++) { 17 insert(objects[i]); 18 } 19 } 20 21 /** Insert element o into the binary tree 22 * Return true if the element is inserted successfully*/ 23 public boolean insert(Object o) { 24 if(root == null) 25 root = new TreeNode(o); 26 else { 27 //Locate the parent node first 28 TreeNode parent = null; 29 TreeNode current = root; 30 while(current != null) { 31 if(((Comparable)o).compareTo(current.element) < 0) { 32 parent = current; 33 current = current.left; 34 } 35 else if(((Comparable)o).compareTo(current.element) > 0) { 36 parent = current; 37 current = current.right; 38 } 39 else 40 return false; //found something already exists. 41 } 42 if(((Comparable)o).compareTo(parent.element) < 0) { 43 parent.left = new TreeNode(o); 44 } 45 else 46 { 47 parent.right = new TreeNode(o); 48 } 49 } 50 size ++; 51 return true; 52 } 53 54 /** Inorder traversal */ 55 public void inorder() { 56 inorder(this.root); 57 } 58 59 /** Inorder traversal from a subtree */ 60 private void inorder(TreeNode root) { 61 if(root == null) return; 62 inorder(root.left); 63 System.out.print(root.element + " "); 64 inorder(root.right); 65 } 66 67 /** Postorder travelsal */ 68 public void postorder() { 69 postorder(this.root); 70 } 71 72 /** Postorder travelsal from a subtree */ 73 private void postorder(TreeNode root) { 74 if (root == null) return; 75 postorder(root.left); 76 postorder(root.right); 77 System.out.print(root.element + " "); 78 } 79 80 /** Preorder traversal */ 81 public void preorder() { 82 preorder(this.root); 83 } 84 85 /** Preorder traversal from a subtree */ 86 private void preorder(TreeNode root) { 87 if(root == null) return; 88 System.out.print(root.element + " "); 89 preorder(root.left); 90 preorder(root.right); 91 } 92 93 /** Get size */ 94 public int getSize() { 95 return size; 96 } 97 }
入口函数中的测试如下:
1 import java.util.ArrayList; 2 3 /** 4 * Created by ��� on 2015/7/6. 5 */ 6 public class Main { 7 public static void main(String[] args) { 8 BinaryTree myBinTree = new BinaryTree(); 9 myBinTree.insert(5); 10 myBinTree.insert(3); 11 myBinTree.insert(2); 12 myBinTree.insert(1); 13 myBinTree.insert(4); 14 myBinTree.insert(5); 15 System.out.println("Size is " + myBinTree.getSize()); 16 System.out.println("Inorder: "); 17 myBinTree.inorder(); 18 System.out.println("\nPostorder: "); 19 myBinTree.postorder(); 20 System.out.println("\nPreorder: "); 21 myBinTree.preorder(); 22 } 23 }
结果如下:
1 Size is 5 2 Inorder: 3 1 2 3 4 5 4 Postorder: 5 1 2 4 3 5 6 Preorder: 7 5 3 2 1 4 8 Process finished with exit code 0
【中序遍历】
首先访问当前节点的左子树,然后访问当前节点,最后访问该节点的右子树。前序首先访问当前节点,后序首先访问左子树,然后是右子树,最后是当前节点。
【广度优先遍历】
【深度优先遍历】