剑指offer(20)二叉搜索树与双向表

题目:

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

思路一:递归法 

1.将左子树构造成双链表,并返回链表头节点。
2.定位至左子树双链表最后一个节点。
3.如果左子树链表不为空的话,将当前root追加到左子树链表。
4.将右子树构造成双链表,并返回链表头节点。
5.如果右子树链表不为空的话,将该链表追加到root节点之后。
6.根据左子树链表是否为空确定返回的节点。
class Untitled {
	
	public static void main(String[] args) {
		TreeNode node1 = new TreeNode(10);
		TreeNode node2 = new TreeNode(6);
		TreeNode node3 = new TreeNode(14);
		TreeNode node4 = new TreeNode(4);
		TreeNode node5 = new TreeNode(8);
		TreeNode node6 = new TreeNode(12);
		TreeNode node7 = new TreeNode(16);
		node1.setNode(node2,node3);
		node2.setNode(node4,node5);
		node3.setNode(node6,node7);
		Solution s = new Solution();
		TreeNode p = s.Convert(node1);
		while(p.right!=null){
			System.out.println(p.val);
			p = p.right;
		}
	}
	
}
	//树的定义
class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }
	
	public void setNode(TreeNode node1,TreeNode node2){
		this.left = node1;
		this.right = node2;
	}

}
//解方法	
class Solution {
    public TreeNode Convert(TreeNode root) { 
        if(root==null) 
            return null; 
        if(root.left==null&&root.right==null) 
            return root; 
// 1.将左子树构造成双链表,并返回链表头节点 
        TreeNode left = Convert(root.left); 
        TreeNode p = left; 
 // 2.定位至左子树双链表最后一个节点
        while(p!=null&&p.right!=null){ 
            p = p.right; 
        } 
// 3.如果左子树链表不为空的话,将当前root追加到左子树链表
        if(left!=null){ 
            p.right = root; 
            root.left = p; 
        } 
// 4.将右子树构造成双链表,并返回链表头节点 
        TreeNode right = Convert(root.right); 
 // 5.如果右子树链表不为空的话,将该链表追加到root节点之后 
        if(right!=null){ 
            right.left = root; 
            root.right = right; 
        } 
        return left!=null?left:root;         
    } 

}

 

 

思路二:

  如果知道二叉搜索树的中序遍历是有序列的话,那么这道题的方法也就呼之欲出了

public class Solution {
    
    TreeNode realHead = null;
    TreeNode head = null;
    
    public TreeNode Convert(TreeNode root) {
        ConvertHelp(root);
        return realHead;
    }
    
    public void ConvertHelp(TreeNode root){
        if(root==null)
            return;
        ConvertHelp(root.left);
        if(realHead==null){
            head = root;
            realHead = root;
        }else{
            head.right = root;
            root.left = head;
            head = root;
        }
        ConvertHelp(root.right);
    }
}

  由于中序遍历的特点,第一次碰到的绝对是最左下的结点,因此可以将头节点赋给他。

posted @ 2019-03-06 19:55  FigSprite  阅读(219)  评论(0编辑  收藏  举报