劍指offer 二叉搜索樹與雙向鏈表

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。

這道題仔細看,就會發現是中序遍歷+改變指針指向。
但我就是那麼菜,明明知道了總體思路還是不會編,最後看了討論區中的高票回答,豁然開朗。
中序遍歷分爲遞歸和非遞歸。
非遞歸遍歷時,由於需要更改指針,所以需要增加一個節點記錄上一次遍歷到的節點。
遞歸遍歷時,就是先遞歸求出左子樹的結果,返回左子樹的雙向鏈表的第一個節點,然後我們對這個雙向鏈表遍歷,得到它的最後一個節點,然後加上root,然後遞歸求右子樹的結果,即右子樹的雙向鏈表的第一個節點,root加上這個節點即可。

方法一:非遞歸遍歷

import java.util.*;
public class Solution {
    public TreeNode Convert(TreeNode root) {
        if(root == null) return null;
        Stack<TreeNode> stack = new Stack<>();
        TreeNode cur = root , pre = null , head = null;
        boolean isFirst = true;
        while(cur != null || !stack.isEmpty()) {
            while(cur != null) {
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            if(isFirst) {
                pre = cur;
                head = cur;
                isFirst = false;
            }else {
                cur.left = pre;
                pre.right = cur;
                pre = cur;
            }
            cur = cur.right;
        }
        return head;
    }
}

方法二:遞歸遍歷

public class Solution {
    public TreeNode Convert(TreeNode root) {
        if(root == null) return null;
        if(root.left == null && root.right == null) return root;
        TreeNode left = Convert(root.left);
        TreeNode p = left;
        while(p != null && p.right != null) {
            p = p.right;
        }
        if(p != null) {
            p.right = root;
            root.left = p;
        }
        TreeNode right = Convert(root.right);
        if(right != null) {
            right.left = root;
            root.right = right;
        }
        return left != null ? left : root;
    }
}

方法二的改進
解題思路:
思路與方法二中的遞歸版一致,僅對第2點中的定位作了修改,新增一個全局變量記錄左子樹的最後一個節點。

public class Solution {
    TreeNode leftLast = null;
    public TreeNode Convert(TreeNode root) {
        if(root == null) return null;
        if(root.left == null && root.right == null) {
            leftLast = root;
            return root;
        }
        TreeNode left = Convert(root.left);
        if(left != null) {
            leftLast.right = root;
            root.left = leftLast;
        }
        leftLast = root;
        TreeNode right = Convert(root.right);
        if(right != null) {
            right.left = root;
            root.right = right;
        }
        return left != null ? left : root;
    }
}
發佈了27 篇原創文章 · 獲贊 3 · 訪問量 2118
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章