您的位置:首页 > 理论基础 > 数据结构算法

关于二叉查找树的平均查找时间的问题

2017-06-29 13:08 405 查看
首先,放附上二叉查找树

package com.company.adt;

/**
* Created by Administrator on 2017/6/2.
*/
public class BiSearchTree<E extends Comparable<? super E>> {
private TreeNode<E> root;
private int count;

public BiSearchTree(){
count=0;
root=null;
}

public BiSearchTree(TreeNode<E> root) {
this.root = root;
count=1;
}

public TreeNode<E> getRoot() {
return root;
}

public void setRoot(TreeNode<E> root) {
this.root = root;
}

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public boolean contains(E x){
return contains(root,x);
}

private boolean contains(TreeNode<E> t, E x) {
if (t!=null){
int compareResult=x.compareTo(t.getX());
if (compareResult>0){
return contains(t.getRight(),x);
}else if (compareResult<0){
return contains(t.getLeft(),x);
}else {
return true;
}
}else {
return false;
}
}

public boolean insert(E x){
return insert(root,x);
}

private boolean insert(TreeNode<E> t, E x) {
int compareResult=x.compareTo(t.getX());
if (compareResult<0){
if (t.getLeft()==null){
TreeNode tmp=new TreeNode(x);
t.setLeft(tmp);
tmp.setParent(t);
return true;
}else {
t=t.getLeft();
insert(t,x);
}
}else if (compareResult>0){
if (t.getRight()==null){
TreeNode tmp=new TreeNode(x);
t.setRight(tmp);
tmp.setParent(t);
return true;
}else {
t=t.getRight();
insert(t,x);
}
}
return false;
}

public void delete(E x){
delete(root,x);
}

private void delete(TreeNode<E> t, E x) {
if (t!=null){
int compareResult=x.compareTo(t.getX());
if (compareResult<0){
delete(t.getLeft(),x);
}else if (compareResult>0){
delete(t.getRight(),x);
}else if(t.getLeft()!=null&&t.getRight()!=null){
//寻找到待删除的节点
TreeNode min=t.getRight();
while (min.getLeft()!=null)
min=min.getLeft();
t.setX((E) min.getX());
delete(t.getRight(), (E) min.getX());
}else{
if(t.getLeft()==null&&t.getRight()!=null){
t.getParent().setRight(t.getRight());
t.getRight().setParent(t.getParent());
}else if (t.getRight()==null&&t.getLeft()!=null){
t.getParent().setLeft(t.getLeft());
t.getLeft().setParent(t.getParent());
}else {
TreeNode tmp=t.getParent();
if (tmp.getLeft()==t)
tmp.setLeft(null);
else
tmp.setRight(null);
}
}
}
}

private boolean isEmpty() {
return root==null;
}
}

以上是二叉查找树的Java实现

那么对于一个具有N个节点的,其内部路径长记为D(N),表示所有节点的深度之和。所以轻易可得D(N)=1.

若一棵二叉树的左子树的其内部路径长用D(i)来表示,则其右子树的内部路径长为D(N-i-1)。

又因为在原树内,左子树与右子树的深度都应当+1,所以最终该树的内部路径长可表示为

D(N)=D(i)+D(N-i-1)+N-1

如果所有子树的概率平均,那么有对于左右子树,有其平均内部路径长为

D(i)=1/N∑D(j)


D(N)=2/N∑D(j) +N-1

上式最终可证O(logN)
因而二叉树的平均查找时间应该是O(logN)。
补充关于上式的证明内容,先去掉-1,如下:

N*D(N)=2∑D(j) +N*N(j的上限为N-1,下限为0)
(1)

轻易可得

(N-1)D(N-1)=2∑D(j)+(N-1)(N-1)(j的上限为N-2,下限为0)
(2)

用(1)-(2)可得

N*D(N)-(N-1)D(N-1)=2D(N-1)+2(N-1)
(3)

经移项可得

N*D(N)=(N+1)D(N-1)+2N-2
(4)

无关项-2去掉,两边同除N(N+1)

D(N)/N+1=D(N-1)/N+2/N+1
D(N-1)/N=D(N-2)/N+2/N
...
D(2)/3=D(1)/2+2/3

将上述各式相加



D(N)/N+1=D(1)/2+2∑1/i(i上限N+1,下限3)

该式近似等于log(N+1),所以D(N)=O(NlogN).
得证。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐