zoukankan      html  css  js  c++  java
  • [原]《面试题精选》12.求二元查找树的镜像

    题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。

    例如输入:

         8
        /  
      6      10
     /       /
    5  7    9   11

    输出:

          8
        /  
      10    6
     /      /
    11  9  7  5

    定义二元查找树的结点为:

    struct BSTreeNode // a node in the binary search tree (BST)
    {
          int          m_nValue; // value of node
          BSTreeNode  *m_pLeft;  // left child of node
          BSTreeNode  *m_pRight; // right child of node
    };


    分析:题目中有提示用到递归和循环,首先我们根据题目的题型很容易想到用递归,即递归交换左右孩子,所以很容易想到递归方法,难的就是实现。之后再由递归变循环----这个非常像树的三种遍历(递归与非递归实现)讲到的变换方法,就是利用栈或队列实现。

    方法一:递归法

    import java.util.* ;
    public class BinaryMirror{
    	public static void main(String args[]){
    		MyBinrryTree tree = new MyBinrryTree() ;
    		tree.add(8);
    		tree.add(6);
    		tree.add(10);
    		tree.add(5);
    		tree.add(7);
    		tree.add(9);
    		tree.add(11);
    		
    		tree.println(tree.root) ; //没镜像前的输出
    
    		tree.println(reversal(tree.root)) ; //镜像后的输出
    	}
    	public static MyTreeNode reversal(MyTreeNode root){
    		MyTreeNode temp = null ;
    		temp = root.left ;
    		root.left = root.right ;
    		root.right = temp ;
    		
    		if(root.left!=null) reversal(root.left) ;
    		if(root.right!=null) reversal(root.right) ;
    		
    		return root ;
    	}
    }
    class MyTreeNode{
    	int key ;
    	MyTreeNode left ;
    	MyTreeNode right ;
    	
    	public MyTreeNode(int x){
    		key = x ;
    	}
    }
    class MyBinrryTree{
    	MyTreeNode root ;
    	
    	public void add(int value){
    		MyTreeNode newNode = new MyTreeNode(value) ;
    		if(root==null){
    			root = newNode ;
    		}else{
    			MyTreeNode x = null ;
    			MyTreeNode y = root ;
    			while(y!=null){
    				if(newNode.key<y.key){
    					x = y ;
    					y = y.left ;
    					
    				}else{
    					x = y ;
    					y = y.right ;
    				}
    			}
    			if(newNode.key<x.key){
    				x.left = newNode ;
    			}else{
    				x.right = newNode ;
    			}
    		}
    	}
    	//二叉树的层次遍历,层次遍历需要用到队列,我们用LinkedList(实现了Queue接口)来实现
    	public void println(MyTreeNode root){
    		LinkedList<MyTreeNode> queue = new LinkedList<MyTreeNode>() ; 
    		queue.add(root) ;
    		MyTreeNode n ;
    		while(queue.size()!=0){     //注意能使使用queue!=null因为queue初始化本来就不是null
    			n = queue.poll() ;
    			System.out.println(n.key) ;
    			if(n.left!=null){
    				queue.add(n.left) ;
    			}
    			if(n.right!=null){
    				queue.add(n.right) ;
    			}
    		}
    	}
    }

    总结:用到的知识点有①.二叉查找树的实现 ②.层次遍历的实现 ③.双层递归法  递归不熟悉的可看:彻底理解递归


    方法二:循环法(只把实现镜像翻转的函数代码列出来,其他部分一样)

    public static MyTreeNode reversal(MyTreeNode root){
    	MyTreeNode temp = null ;
    	MyTreeNode n = null ;
    	
    	LinkedList<MyTreeNode> queue = new LinkedList<MyTreeNode>() ;
    	queue.add(root) ;
    	
    	while(queue.size()!=0){
    		n = queue.poll() ;
    		if(n.left!=null) queue.add(n.left) ;
    		if(n.right!=null) queue.add(n.right) ;
    		temp = n.left ;
    		n.left = n.right ;
    		n.right = temp ;
    	}
    	return root ;
    }

    总结:其实只要你熟悉树的三种遍历(递归与非递归实现),这个问题就很简单了,就是利用到队列存储来实现循环交换。


    最后总结下,这道题又说明了《Thinking In Algorithm》系列有多重要了,其中的

    基本上自己掌握了上面两篇博客的话,这种类型的题目肯定没问题的。

    作者:SpeedMe 发表于2014-4-16 14:53:53 原文链接
    阅读:97 评论:0 查看评论
  • 相关阅读:
    跨站攻击与文件上传漏洞
    时光变奏曲
    概率论知识总结(1)——集合、概率和计数
    电磁学知识点提要
    解析几何
    数据库与信息系统经典例题
    复变函数知识总结——复变函数作业解答与问题注释
    复变函数知识总结(4)——共形映射
    复变函数知识总结(3)——亚纯函数与对数函数
    复变函数知识总结(2)——Cauchy理论
  • 原文地址:https://www.cnblogs.com/huanglei/p/3677692.html
Copyright © 2011-2022 走看看