给出两个二叉搜索树,把它们节点的值按升序排到一个list里。
思路:
因为是二叉搜索树(BST),所以它的中序遍历就是升序排列。
现在有两个BST,可以让它们同时中序遍历。
可以想到的一个方法是两个BST的指针都指向最左边的节点,哪个值小就把哪个装入list,然后移向下一节点。
正常中序遍历我们是用递归实现的,如下
midOrder(root) {
midOrder(root.left);
root.val;
midOrder(root.right);
}
这样的不便于同时遍历两个BST
写成while形式拆解一下
while(root!=null || !stack.isEmpty()) {
//保存中间节点,root到最左边节点
while(root!= null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
root.val;
//相当于midOrder(root.right)
root = root.right;
}
拆解开以后,就可以同时遍历两个BST,不同的是中间root.val的部分要比较root1.val和root2.val的大小,
把较小的值放入list。
public List<Integer> getAllElements(TreeNode root1, TreeNode root2) {
List<Integer> result = new ArrayList<>();
if(root1 == null && root2 == null) return result;
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
while(root1 != null || root2 != null || !stack1.isEmpty() || !stack2.isEmpty()) {
while(root1 != null) {
stack1.push(root1);
root1 = root1.left;
}
while(root2 != null) {
stack2.push(root2);
root2 = root2.left;
}
//stack2和stack1一定不会同时为空,因为如果同时为空,root1和root2就会同时为null(前面有两个push),不会进入循环
if(stack2.isEmpty() || !stack1.isEmpty() && stack1.peek().val < stack2.peek().val) {
root1 = stack1.pop();
result.add(root1.val);
root1 = root1.right;
} else {
root2 = stack2.pop();
result.add(root2.val);
root2 = root2.right;
}
}
return result;
}