二叉树的前序遍历,中序遍历,后续遍历的思想,对其应分别对应的介绍了快速排序、汉诺塔、归并排序。二叉树的增删查操作很普通,时间复杂度与链表并没有太多差别。但当二叉树具备一些特性的时候,则可以利用这些特性实现时间复杂度的降低。
二叉查找树/排序树/搜索树
二叉查找树(也称作二叉排序树,二叉搜索树)具备以下几个的特性:
-
若左子树不为空,那么左子树上面的所有节点的关键字值都比根节点的关键字值小
-
若右子树不为空,那么右子树上面的所有节点的关键字值都比根节点的关键字值大
-
左右子树都为二叉树
-
没有重复值(这一点在实际中可以忽略)
-
对二叉查找树进行中序遍历,就可以输出一个从小到大的有序数据队列,如下图所示,中序遍历的结果就是 10、13、15、16、20、21、22、26。
二叉查找树的查找操作
在利用二叉查找树执行查找操作时,我们可以进行以下判断:
-
首先判断根结点是否等于要查找的数据,如果是就返回。
-
如果根结点大于要查找的数据,就在左子树中递归执行查找动作,直到叶子结点。
-
如果根结点小于要查找的数据,就在右子树中递归执行查找动作,直到叶子结点。
这样的“二分查找”所消耗的时间复杂度就可以降低为 O(logn)。关于二分查找,我们会在后续的分治法一讲中详细讲述。
public class BinarySearchTree {
/**
* 根结点
*/
public TreeNode root;
public class TreeNode{
int data;
TreeNode leftChild;
TreeNode rightChild;
TreeNode parent;
public TreeNode(int data) {
this.data = data;
this.leftChild = null;
this.rightChild = null;
this.parent = null;
}
}
/**
* 查找结点
*/
public TreeNode searchNode(int data) {
if (root == null) {
return null;
}
TreeNode node = root;
while (node != null) {
if (data > node.data) {
node = node.rightChild;
} else if (data < node.data) {
node = node.leftChild;
} else {
return node;
}
}
return null;
}
/**
* 中序遍历
*/
public void midOrderTraverse(TreeNode root) {
if (root == null) {
return;
}
//LDR
midOrderTraverse(root.leftChild);
System.out.print(root.data+" ");
midOrderTraverse(root.rightChild