用线性表作为表的组织形式时,用二分查找效率最高。但二分查找只能用于顺序存储结构,不能用链式存储结构,不适用于插入删除操作频繁的情况,只适合静态查找表。
对动态查找表进行高效率查找,最好用二叉排序树。
1.基本概念
二叉排序树(Binary Sort Tree):为空或满足以下条件:
(1)每个结点左子树上所有结点的关键字,值都小于该结点的关键字;
(2)每个结点右子树上所有结点的关键字,值都大于该结点的关键字;
(3 )左右子树本身也是二叉排序树。
2.特点
(1)对任一节点x,左(右)子树任一结点y的关键字必小于(大于)x的关键字;
(2)各结点关键字是唯一的,(但实际应用不能保证元素都不相同,此时可以将左子树关键字改为小于等于,或者右子树关键字大于等于)
(3)按中序遍历该树得到的是递增有序序列。
3.二叉排序树的插入和生成
初始二叉树为空,然后读入元素,插入树中。已知关键字为key的结点s,将其插入到二叉排序树中:
(1)二叉树为空,key为二叉树的根;
(2)非空,如果key小于根结点的值,则插入左子树,如果key大于根结点的值,则插入右子树,等于的话停止插入。
Node类:
//二叉树结点类
public class Node {
private Integer data;
private Node left;
private Node right;
public Node() {}
public Node(int data) {
this.data=data;
}
public Integer getData() {
return this.data;
}
public void setData() {
this.data=data;
}
//得到左子树
public Node getLeft() {
return this.left;
}
public Node getRight() {
return this.right;
}
public void setLeft(Node left) {
this.left=left;
}
public void setRight(Node right) {
this.right=right;
}
}
创建和插入结点实现:
public Node createBST(Node root,int []datas) {
root=null;
int index=0;
while(index<datas.length)
{
root=insertBST(root,datas[index]);
index++;
}
return root;
}
//插入元素,非递归
public Node insertBST(Node root,int data) {
Node insertNode=new Node(data);
while(root!=null) {
if(root.getData()==data) {
System.out.println("该元素已存在");
return root;
}
else if(data<root.getData()) {
if(root.getLeft()!=null) {
root=root.getLeft();
}
else {
root.setLeft(insertNode);
return root;
}
}
else if(data>root.getData()) {
if(root.getRight()!=null) {
root=root.getRight();
}
else {
root.setRight(insertNode);
return root;
}
}
}
root=insertNode;
return root;
}
//插入元素 递归
public Node rInsertBST(Node root,int data) {
Node insertNode=new Node(data);
if(root==null) {
root=insertNode;
}
else if(data<root.getData()) {
root=root.getLeft();
root=rInsertBST(root,data);
}
else if(data>root.getData()) {
root=root.getRight();
root=rInsertBST(root,data);
}
return root;
}
4.查找
查找的元素key与当前结点的值data比较,如果key<data则到当前结点的左子树搜索;如果key>data则到当前结点的右子树搜索;
key==data则找到该元素;
一直搜索到空,则不存在要找的元素。
public boolean search(Node root,int data) {
while(root!=null) {
if(root.getData()==data)
return true;
else if(data<root.getData())
root=root.getLeft();
else if(data>root.getData())
root=root.getRight();
}
return false;
5.算法分析
(1)二叉排序树等概率下,查找成功时平均查找长度为
(2)二叉排序树查找的平均查找长度与二叉树的形态有关
n个结点的二叉排序树不唯一,结点插入顺序不同,树的形态和深度也不同
a.最坏情况下,是深度为n 的单支树,平均查找长度和顺序表一样是(n+1)/2
b.最好情况下,树的形态比较均匀,得到的是与二分查找的判定树相似的二叉排序树,平均查找长度为lgn
c.插入、删除的时间复杂度均为O(lgn)