输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
采用中序遍历的方法,当遇到出栈节点的时候,做指针的指向操作,当前节点的右指针指向下一个节点,下一个节点的左指针指向当前节点,注意第一个节点的指针有所不同,当然如果一开始将pre设为空,好像也可以都一样。
import java.util.Stack;
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
//主要思路是非递归的中序遍历搜索二叉树怎么做,然后在输出节点的地方进行操作即可
//这道题因为采用非递归肯定要开辟空间。跟题目有一点点不符合。
public TreeNode Convert(TreeNode pRootOfTree) {
Stack<TreeNode> stack = new Stack<TreeNode>();
if(pRootOfTree==null)
return null;
TreeNode pre = null;
TreeNode p = pRootOfTree;
//用来判断第一个节点
boolean isFirst = true;
while(p!=null||!stack.isEmpty())
{
//中序遍历思想,左边存在一直往左走
while(p!=null)
{
stack.push(p);
p = p.left;
}
//当来到左尽头的时候,开始输出
p = stack.pop();
if(isFirst)
{
//第一个节点特殊处理
pRootOfTree = p;
pre = pRootOfTree;
isFirst = false;
}
else{
//后序节点,前一个节点的右指针指向下一个节点,下一个节点的作指针指向前一个节点
pre.right = p;
p.left = pre;
pre = p;
}
p = p.right;
}
return pRootOfTree;
}
}
这是我的思路,因为利用到栈来存储,空间复杂度为O(n),所以下面就有一个大神采用了一种我听都没听过的Morris Traversal方法来实现,这个方法的空间复杂度为O(1)
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
TreeNode p = pRootOfTree, pre = null, res = null;
while (p != null) {
while (p.left != null) {
TreeNode q = p.left;
while (q.right != null) {
q = q.right;
}
q.right = p;
TreeNode tmp = p.left;
p.left = null;
p = tmp;
}
p.left = pre;
if (pre == null) {
res = p;
} else {
pre.right = p;
}
pre = p;
p = p.right;
}
return res;
}
}