zoukankan      html  css  js  c++  java
  • 节点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
    ---------------------------------

  • 相关阅读:
    windows下忘记mysql超级管理员root密码的解决办法
    windows防火墙支持FTP服务的设置方法
    IT人士不得不看的保健手册
    利用Google开发接口获取Google用户信息,OAuth2.0,profiles
    一个简单抓取糗事百科糗事的小程序
    JAVA 数据库编程
    JAVA 数据库编程(1)
    JAVA 数据库编程(2)
    css快速入门
    html5和css3新增特性
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3108952.html
Copyright © 2011-2022 走看看