• 剑指offer-二叉搜索树与双向链表


    输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

    这题做了好久,但是后面看来并不是想象中那么难。

    例如一棵树

    其实链表的顺序就是这棵树中根遍历的顺序,所以我想到了用递归或者非递归。

    非递归的做法就是用栈对这棵树进行中根遍历,

    用栈进行中根遍历的思路是,根节点的左子树先入栈,然后出栈,栈顶元素的右孩子入栈,直到栈空为止。

    构建双链表时,记录前一个入栈的节点previous,当前出栈的节点current,然后把他们关联起来。

    public static TreeNode Convert(TreeNode pRootOfTree) {
    	 		if(pRootOfTree==null){
    	 			return null;
    	 		}
    	 		if(pRootOfTree.left==null&&pRootOfTree.right==null){
    	 			return pRootOfTree;
    	 		}
    	 		//创建一个栈
    	 		LinkedList stack = new LinkedList();
    	 		TreeNode node =pRootOfTree;
    	 		//所有的左节点入栈
    	 		while(node!=null){
    	 			stack.push(node);
    	 			node=node.left;
    	 		}
    	 		TreeNode prehead=new TreeNode(0);
    	 		TreeNode previous=prehead;
    	 		//当栈不为空时
    	 		while(!stack.isEmpty()) {
    	 			//弹出栈顶元素
    	 			TreeNode current=(TreeNode) stack.pop();
    	 			//栈顶元素的右孩子入栈
    	 			if(current.right!=null) {
    	 				stack.push(current.right);
    	 				node=current.right.left;
    		 			while(node!=null){
    		 				stack.push(node);
    		 				node=node.left;
    		 			}
    	 			}
    	 			//将之前出栈的点和现在出栈的点建立联系
    	 			previous.right=current;
    	 			current.left=previous;
    	 			previous=current;
    	 		
    	 		}
    	 		TreeNode newHead=prehead.right;
    	 		newHead.left=null;
    	 		return newHead;
    	 		
     }
    

    递归做法我想了很久,因为总是想不到怎样把之前遍历过的记下来,剑指offer里面的好像也不对。

    思路:

    事实上根节点的left是指向左子树的最后一个节点,也就是最右边的节点,根节点的right是指向右子树最左边的节点。

    根据这个规律,可以递归实现。

    public static TreeNode convert(TreeNode pRootOfTree){
    		if(pRootOfTree==null) {
    			return null;
    		}
    		if(pRootOfTree.left==null&&pRootOfTree.right==null) {
    			return pRootOfTree;
    		}
    		//将左子树构造成双链表,并返回头节点
    		TreeNode left=convert(pRootOfTree.left);
    		TreeNode p=left;
    		//将左子树最后一个节点获取
    		while(p!=null&&p.right!=null) {
    			p=p.right;
    		}
    		if(p!=null) {
    			pRootOfTree.left=p;
    			p.right=pRootOfTree;
    		}
    		//将右子树构造成双链表,并返回头节点
    		TreeNode right=convert(pRootOfTree.right);
    		p=right;
    		//获取右子树的第一个节点
    		while(p!=null&&p.left!=null) {
    			p=p.left;
    		}
    		//若p不为空,关联pRootOfTree
    		if(p!=null) {
    			pRootOfTree.right=p;
    			p.left=pRootOfTree;
    		}
    		//判断left是否为空是为了避免没有左子树的情况
    		return left==null?pRootOfTree:left;
    }
    

      

  • 相关阅读:
    Java注解
    java反射简单入门
    java泛型反射
    BeanUtils.populate的作用
    适配器模式
    原型模式
    抽象工厂模式
    工厂方法模式
    建造者模式
    单例模式
  • 原文地址:https://www.cnblogs.com/qingfei1994/p/4917470.html
Copyright © 2020-2023  润新知