首先,放附上二叉查找树
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).
得证。