节点node[算法导论]二叉排序树(Binary Search Tree)

新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

    1. 二叉排序树的定义

    它或者是一棵空树;或者是拥有下列性子的二叉树:

           (1)若左子树不空,则左子树上全部结点的值均小于它的根结点的值;

           (2)若右子树不空,则右子树上全部结点的值均大于它的根结点的值;

           (3)左、右子树也分别为二叉排序树;

    2. java实现代码(注:以下代码参考网上优良代码,均已编写实现)

    每日一道理
试试看——不是像企鹅那样静静的站在海边,翘首企盼机会的来临,而是如苍鹰一般不停的翻飞盘旋,执著的寻求。 试试看——不是面对峰回路转、杂草丛生的前途枉自嗟叹,而是披荆斩棘,举步探索。 试试看——不是拘泥于命运的禁锢,听凭命运的摆布,而是奋力敲击其神秘的门扉,使之洞开一个新的天地。微笑着,去唱生活的歌谣。
/*
 * 注:该代码实现了二叉查找树的全部操作:包括,插入、删除、查找、排序输出、前驱、后继等。
 * */
import java.util.ArrayList;
import java.util.List;
public class BinarySearchTree {
    // 二叉查找树的根节点
	private TreeNode root = null ;
	private List<TreeNode> nodelist = new ArrayList<TreeNode>();
	
	// 二叉树的节点类
	private class TreeNode{
		private int key ;
		private TreeNode leftChild ;
		private TreeNode rightChild ;
		private TreeNode parent ;
		// 构造器
		public TreeNode(int key , TreeNode leftChild , TreeNode rightChild , TreeNode parent)
		{
			this.key = key ;
			this.leftChild = leftChild ;
			this.rightChild = rightChild ;
			this.parent = parent ;
		}
		
		public int getKey()
		{
			return key ;
		}
		
		public String toString()
		{
		    String leftkey = (leftChild == null ? "" : String.valueOf(leftChild.key));
		    String rightkey = (rightChild == null ? "" : String.valueOf(rightChild.key));
		    return "("+leftkey+","+key+","+rightkey+")";
		}
	}
	
	/*
	 * 判断二叉查找树是不是为空;若为空,返回true,否则返回false
	 * */
	public boolean isEmpty()
	{
		if(root == null){
			return true ;
		}else{
			return false ;
		}
	}
	
	/*
	 * 对于某些二叉查找树操作(比如删除关键字)来说,若树为空,则抛出异常。
	 * */
	public void TreeEmpty() throws Exception
	{
	     if(isEmpty()){
	    	 throw new Exception("树为空!");
	     }
	}
	
	/*
	 * 在二叉查找树中查询给定关键字的节点
	 * */
	public TreeNode search(int key)
	{
		TreeNode pNode = root ;
		while(pNode!=null && pNode.key !=key)
		{
			if(key<pNode.key){
				pNode = pNode.leftChild;
			}else{
				pNode = pNode.rightChild;
			}
		}
		return pNode ;
	}
	
	/*
	 * 获得二叉查找树中的最小关键字节点
	 * */
	public TreeNode minTreeNode(TreeNode node)throws Exception{
		if(node == null)
			throw new Exception("树为空!");
		TreeNode pNode = node ;
		while(pNode.leftChild!=null)
		{
			pNode = pNode.leftChild ;
		}
		
		return pNode ;
	}
	
	/*
	 * 获得二叉查找树中的最大关键字的节点
	 * */
	public TreeNode maxTreeNode(TreeNode node)throws Exception{
		if(node == null)
			throw new Exception("树为空!");
		TreeNode pNode = node ;
		while(pNode.rightChild!=null)
		{
			pNode = pNode.rightChild ; 
		}
		return pNode ;
	}
	
	/*
	 * 查找给定节点在中序遍历下的后继节点
	 * */
	public TreeNode successor(TreeNode node)throws Exception{
		if(node == null)
			return null ;
		
		// 若该节点的右子树不为空,则它的后继节点为右子树中的最小关键字节点
		if(node.rightChild!=null){
			return minTreeNode(node.rightChild);
		}
		
		// 右子树为空的情况
		TreeNode pNode = node.parent ;
		while(pNode!=null && node == pNode.rightChild){
			node = pNode ;
			pNode = pNode.parent;
		}
		return pNode ;
	}
	
	/*
	 * 查找给定节点在中序遍历下的前驱节点
	 * */
	public TreeNode precursor(TreeNode node)throws Exception{
		if(node == null)
			return null;
		
		// 若节点的左子树不为空,则它的前驱节点就是左子树中的最大节点
		if(node.leftChild!=null){
			return maxTreeNode(node.leftChild);
		}
		
		// 左子树为空的情况
		TreeNode pNode = node.parent ;
		while(pNode!=null&&node==pNode.leftChild){
			node = pNode ;
			pNode = pNode.parent;
		}
		return pNode ;
	}
	
	/*
	 * 将给定的关键字插入到二叉查找树中
	 * */
	public void insert(int key){
		TreeNode node = null ;
		TreeNode newNode = new TreeNode(key,null,null,null);
		TreeNode pNode = root ;
		if(root==null){
			root = newNode ;
			return ;
		}
		
		while(pNode!=null){
			node = pNode ;
			if(key<pNode.key){
				pNode = pNode.leftChild ;
			}else if(key > pNode.key){
				pNode = pNode.rightChild;
			}else{  // 树中已存在给定的关键字节点了
				return ;
			}
		}
		if(key<node.key){
			node.leftChild = newNode ;
			newNode.parent = node ;
		}else{
			node.rightChild = newNode ;
			newNode.parent = node ;
		}
	}
	
	
	/*
	 * 从二叉查找树中删除给定的节点
	 * */
	public void delete(int key)throws Exception{
		TreeNode pNode = search(key);
		if(pNode == null){
			throw new Exception("树中不存在要删除的关键字!");
		}
		delete(pNode);
	}
	
	private void delete(TreeNode pNode)throws Exception{
		if(pNode.leftChild ==null && pNode.rightChild ==null){// 第一种情况:要删除的节点既无左孩子,又无右孩子
			TreeNode parentNode = pNode.parent ;
			if(pNode == parentNode.leftChild){
				parentNode.leftChild = null ;
			}else{
				parentNode.rightChild = null ;
			}
			return ;
		}
		
		if(pNode.leftChild == null && pNode.rightChild != null){// 第二种情况:要删除节点的左子树为空,右子树不为空
			TreeNode parentNode = pNode.parent ;
			if(pNode == parentNode.leftChild){
				parentNode.leftChild = pNode.rightChild;
				pNode.rightChild.parent = parentNode;
			}else{
				parentNode.rightChild = pNode.rightChild;
				pNode.rightChild.parent = parentNode;
			}
			return ;
		}
		
		if(pNode.leftChild !=null && pNode.rightChild ==null){// 第三种情况,要删除节点的左子树不为空,右子树为空
			TreeNode parentNode = pNode.parent ;
			if(pNode == parentNode.leftChild){
				parentNode.leftChild = pNode.leftChild ;
				pNode.leftChild.parent = parentNode;				
			}else{
				parentNode.rightChild = pNode.leftChild;
				pNode.leftChild.parent = parentNode;
			}
			return ;
		}
		
		// 第四种情况,要删除节点的左右子树都不为空,则删除该节点的后继,并用该结点的后继代替该结点
		TreeNode successorNode = successor(pNode);
		delete(successorNode);
		pNode.key = successorNode.key;
	}
	
	
	/*
	 * 获得二叉查找树中中序遍历的【节点】列表
	 * */
	public List<TreeNode> inorderTraverseList(){
		if(nodelist!=null){
			nodelist.clear();
		}
		inorderTraverse(root);
		return nodelist;
	}
	
	public void inorderTraverse(TreeNode root){
		if(root!=null){
			inorderTraverse(root.leftChild);
			nodelist.add(root);
			inorderTraverse(root.rightChild);
		}
	}
	
	/*
	 * 获得二叉查找树中中序遍历的【关键字】列表
	 * */
	public String toStringOfOrderList(){
		StringBuilder sBuilder = new StringBuilder("[");
		for(TreeNode p : inorderTraverseList()){
			sBuilder.append(p.key);
			sBuilder.append(" ");
		}
		sBuilder.append("]");
		return sBuilder.toString();
	}
	
	/*
	 * 获得二叉查找树的字符串表示
	 * */
	public String toString()
	{
		StringBuilder sBuilder = new StringBuilder("[");
		for(TreeNode p : inorderTraverseList()){
			sBuilder.append(p);   // 注:这里是和上面的区分
			sBuilder.append(" ");
		}
		sBuilder.append("]");
		return sBuilder.toString();
	}
	
	public TreeNode getRoot()
	{
		return root ;
	}
	
	public static void testNode(BinarySearchTree bst , TreeNode pNode)throws Exception
	{
		System.out.println("本结点: " + pNode);  
        System.out.println("前趋结点: " + bst.precursor(pNode));  
        System.out.println("后继结点: " + bst.successor(pNode));  
	}
	
	public static void testTraverse(BinarySearchTree bst) {  
        System.out.println("二叉树遍历:" + bst);  
        System.out.println("二叉查找树转换为有序列表: " + bst.toStringOfOrderList());  
    }  
	
	public static void main(String[] args)
	{
		try{
			int delkey = 15 ;
			BinarySearchTree bst = new BinarySearchTree();
			System.out.println("二叉查找树是不是为空?"+(bst.isEmpty()?"是":"否"));
			int[] keys = new int[]{15,6,18,3,7,13,20,2,9,4};
			for(int key : keys){
				bst.insert(key);
			}
			System.out.println("二叉查找树是不是为空?"+(bst.isEmpty()?"是":"否"));
			TreeNode minkeyNode = bst.minTreeNode(bst.getRoot());
			System.out.println("最小关键字:"+minkeyNode.getKey());
			testNode(bst,minkeyNode);
			TreeNode maxKeyNode = bst.maxTreeNode(bst.getRoot());  
            System.out.println("最大关键字: " + maxKeyNode.getKey());  
            testNode(bst, maxKeyNode);  
            System.out.println("根结点关键字: " + bst.getRoot().getKey());  
            testNode(bst, bst.getRoot());  
            testTraverse(bst);  
            System.out.println("删除关键字6后的二叉查找树:");
            bst.delete(delkey);
            System.out.println("删除根节点后的根节点:"+bst.getRoot().getKey());
            testNode(bst,bst.getRoot());
            testTraverse(bst);
            System.out.println("****************************** ");  
		}catch(Exception e){
			System.out.println(e.getMessage());
			e.printStackTrace();
		}
	}
}

    3. 代码运行结果:

                                   节点和node

    保持天天的学习,加油!!!

文章结束给大家分享下程序员的一些笑话语录: 一条狗在街上闲逛,看见橱窗里一张告示:「招聘程序员。会编程,有团队精神,至少精通两种语言。均等机会。」
  那条狗就进去申请,但是被拒绝了。
  「我不能雇一条狗在公司里做事。」经理说。
  狗不服气,指着告示上「均等机会」几字抗议。
  经理没法,叹了口气,不屑地问道:「你会编程吗?」
  那条狗默默地走到电脑前,编了个程序,运作准确。
  「你有团队精神吗?」经理问。
  那条狗掉头看了看门外,一大群野狗在外面虎视耽耽。
  「我真的不能雇狗做这份工作。」经理气急败坏地说。
  「就算会编程、有团队精神,但是我需要的雇员至少要能精通两种语言。」
  那条狗抬头看着经理说:「喵-噢。」

--------------------------------- 原创文章 By
节点和node
---------------------------------

posted @ 2013-05-30 20:17  xinyuyuanm  阅读(260)  评论(0编辑  收藏  举报