1.二叉搜索树定义
二叉搜索树,是指一棵空树或者具有下列性质的二叉树:
- 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值;
- 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值;
- 任意节点的左,右子树也分别为二叉搜索树;
- 没有键值相等的节点。
2.用Java来表示二叉树
public class BinarySearchTree { // 二叉搜索树类 private class Node { // 节点类 int data; // 数据域 Node right; // 右子树 Node left; // 左子树 } private Node root; // 树根节点 }
首先,需要一个节点对象的类。这个对象包含数据域和指向节点的两个子节点的引用。
其次,需要一个树对象的类。这个对象包含一个根节点root。
3.创建树(insert)
public void insert(int key) { Node p=new Node(); //待插入的节点 p.data=key; if(root==null) { root=p; } else { Node parent=new Node(); Node current=root; while(true) { parent=current; if(key>current.data) { current=current.right; // 右子树 if(current==null) { parent.right=p; return; } } else //本程序没有做key出现相等情况的处理,暂且假设用户插入的节点值都不同 { current=current.left; // 左子树 if(current==null) { parent.left=p; return; } } } } }
创建树的时候,主要用到了parent,current来记录要插入节点的位置。哪么怎么检验自己是否正确地创建了一颗二叉搜索树呢,我们通过遍历来输出各个节点的值
4.遍历树(travel)
遍历指的是按照某种特定的次序来访问二叉搜索树中的每个节点,主要有三种遍历的方法:
- 前序遍历,“中左右”
- 中序遍历,“左中右”
- 后续遍历,“左右中”
上面的口诀“中左右”表示的含义是,先访问根节点,再访问左子,最后访问右子。举个例子:
- 前序遍历:39 24 23 30 64 53 60
- 中序遍历:23 24 30 39 53 60 64
- 后序遍历:23 30 24 60 53 64 39
你会发现,按照中序遍历的规则将一个二叉搜索树输入,结果为按照正序排列。
public void preOrder(Node root) { // 前序遍历,"中左右" if (root != null) { System.out.print(root.data + " "); preOrder(root.left); preOrder(root.right); } } public void inOrder(Node root) { // 中序遍历,"左中右" if (root != null) { inOrder(root.left); System.out.print(root.data + " "); inOrder(root.right); } } public void postOrder(Node root) { // 后序遍历,"左右中" if (root != null) { postOrder(root.left); postOrder(root.right); System.out.print(root.data + " "); } } public void traverse(int traverseType) { // 选择以何种方式遍历 switch (traverseType) { case 1: System.out.print("preOrder traversal "); preOrder(root); System.out.println(); break; case 2: System.out.print("inOrder traversal "); inOrder(root); System.out.println(); break; case 3: System.out.print("postOrder traversal "); postOrder(root); System.out.println(); break; } }
以上的代码采用递归的方式实现三种遍历,为了方便我们使用,又写了一个traverse函数来实现选择哪种方式进行树的遍历。
这会儿就可以写单元测试了,我们首先创建一个二叉搜索树,然后分别使用“前序”,“中序”,“后序”来遍历输出树的所有节点。
public static void main(String[] args) //unit test { BinarySearchTree tree=new BinarySearchTree(); tree.insert(39); tree.insert(24); tree.insert(64); tree.insert(23); tree.insert(30); tree.insert(53); tree.insert(60); tree.traverse(1); tree.traverse(2); tree.traverse(3); }
运行该单元测试,可以看到如下的结果: