二叉查找树

原创
2013/10/04 17:01
阅读数 126

二叉查找树的特点:

1.若左子树非空,则左子树上所有结点的数据元素值均小于根结点的数据元素值。

2.若右子树非空,则右子树上所有的节点的数据元素值均大于或等于根结点的数据元素的值。

3.左右子树也均为二叉查找树

java 实现的二叉查找树:

BiTreeNode.java


public class BiTreeNode<T extends Comparable<? super T>> {
	private BiTreeNode<T> leftChild;
	private BiTreeNode<T> rightChild;
	private BiTreeNode<T> parent;
	private T data;
	
	public BiTreeNode() {
		leftChild = null;
		rightChild = null;
	}
	
	public BiTreeNode(T data){
		this.data = data;
		leftChild = null;
		rightChild = null;
	}
	
	BiTreeNode(T data,BiTreeNode<T> leftChild,BiTreeNode<T> rightChild){
		this.data = data;
		this.leftChild = leftChild;
		this.rightChild = rightChild;
	}

	public BiTreeNode<T> getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(BiTreeNode<T> leftChild) {
		this.leftChild = leftChild;
	}

	public BiTreeNode<T> getRightChild() {
		return rightChild;
	}

	public void setRightChild(BiTreeNode<T> rightChild) {
		this.rightChild = rightChild;
	}

	public BiTreeNode<T> getParent() {
		return parent;
	}

	public void setParent(BiTreeNode<T> parent) {
		this.parent = parent;
	}

	public T getData() {
		return data;
	}

	public void setData(T data) {
		this.data = data;
	}
}
BiSearchTree.java



public class BiSearchTree<T extends Comparable<? super T>> {

	private BiTreeNode<T> root;
	
	//中序遍历
	private void inOrder(BiTreeNode<T> t,Visit vs){
		if( t != null ){
			inOrder(t.getLeftChild(),vs);
			vs.print(t.getData());
			inOrder(t.getRightChild(),vs);
		}
	}
	
	//前序遍历
	private void preOrder(BiTreeNode<T> t, Visit vs){
		if(t!=null){
			vs.print(t.getData());
			preOrder(t.getLeftChild(),vs);
			preOrder(t.getRightChild(),vs);
		}
	}
	
	public BiSearchTree() {
		root = null;
	}

	public BiTreeNode<T> getRoot() {
		return root;
	}

	public void setRoot(BiTreeNode<T> root) {
		this.root = root;
	}
	
	
	public void inOrder(Visit vs){
		inOrder(root,vs);
	}

	public void preOrder(Visit vs){
		preOrder(root,vs);
	}
	
	//取得左孩子
	public BiTreeNode<T> getLeft(BiTreeNode<T> current){
		return current != null ?current.getLeftChild():null;
	}
	
	//取得右孩子
	public BiTreeNode<T> getRight(BiTreeNode<T> current){
		return current != null ? current.getRightChild() : null;
	}
	
	//查找
	public BiTreeNode<T> find(T data){
		if(root !=null){
			BiTreeNode<T> temp = root;
			while(temp!=null){
				if(temp.getData().compareTo(data)==0) return temp;
				if((temp.getData().compareTo(data))<0){
					temp = temp.getRightChild();
				} else {
					temp = temp.getLeftChild();
				}
			}
		}
		return null;
	}
	
	public void insert(BiTreeNode<T> ptr,T data){
		
		//如果插入的值小于当前节点的值,就在左子树上面插入
		if(data.compareTo(ptr.getData())<0){
			//如果左字树为空直接把该结点作为当前节点的左孩子,否则递归到左孩子
			if(ptr.getLeftChild() == null){
				BiTreeNode<T> temp  = new BiTreeNode<T>(data);
				temp.setParent(ptr);
				ptr.setLeftChild(temp);
			}else{
				insert(ptr.getLeftChild(),data);
			}
		}else if(data.compareTo(ptr.getData())>0){
			if(ptr.getRightChild() == null){
				BiTreeNode<T> temp  = new BiTreeNode<T>(data);
				temp.setParent(ptr);
				ptr.setRightChild(temp);
			}else{
				insert(ptr.getRightChild(),data);
			}
		}
		
	}
	
	/**
	 * 分四种情况:
	 * 1.删除节点没有孩子节点
	 * 2.删除节点只有左边孩子
	 * 3.删除结点只有右孩子
	 * 4.删除结点有左右结点
	 */
	public void delete(BiTreeNode<T> ptr,T data){
		if(ptr != null){
			if(data.compareTo(ptr.getData())<0){
				delete(ptr.getLeftChild(),data);
			}else if(data.compareTo(ptr.getData())>0){
				delete(ptr.getRightChild(),data);
			}else if(ptr.getLeftChild() != null && ptr.getRightChild() !=null){//删除结点有左右结点
				BiTreeNode<T> rightMin; //右子树最小的结点
				rightMin = ptr.getRightChild();
				while(rightMin.getLeftChild()!=null){
					rightMin = rightMin.getLeftChild();
				}
				ptr.setData(rightMin.getData());
				delete(ptr.getRightChild(),rightMin.getData());
			}else{
				//左孩子为空,右孩子不为空
				if(ptr.getLeftChild() == null &&ptr.getRightChild() !=null){//删除结点只有右孩子
					ptr.getParent().setRightChild(ptr.getRightChild());
					ptr.getRightChild().setParent(ptr.getParent());
				}
				else if(ptr.getLeftChild() != null && ptr.getRightChild() == null){//删除节点只有左边孩子
					ptr.getParent().setLeftChild(ptr.getLeftChild());
					ptr.getLeftChild().setParent(ptr.getParent());
				}else{//删除节点没有孩子节点
					BiTreeNode<T> p = ptr.getParent();
					if(p.getLeftChild() == ptr){
						p.setLeftChild(null);
					}else{
						p.setRightChild(null);
					}
				}
			}
		}
	}
}

测试:

public class BiSearchTreeTest {

	public static void main(String[] args) {
		BiSearchTree<Integer> searchTree = new BiSearchTree<Integer>();
		int a[] = {4,5,7,2,1,9,8,11,3};
		Visit vs = new Visit();
		BiTreeNode<Integer> root = new BiTreeNode<Integer>(a[0]);
		
		for (int i = 1; i < a.length; i++) {
			searchTree.insert(root, a[i]);
		}
		
		searchTree.setRoot(root);
		
		System.out.println("中序遍历:");
		searchTree.inOrder(vs);
		searchTree.delete(searchTree.getRoot(), 4);
		System.out.println("删除4后的中序遍历:");
		searchTree.inOrder(vs);
		
	}

}
public class Visit {
 public void print(Object o){
 System.out.print(o+" ");
 }
}


展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部