题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解答
首先从根节点开始,一直遍历右子节点temp并把它们(包括根节点)依次压栈。
然后再把栈顶节点出栈,判断当前目标双向链表的头(newHead)是不是空,如果为空则将出栈的第一个节点(即原二叉树的最右边的叶子节点)设置为newHead;不为空则将出栈的节点small和newHead连在一起,并将small设为新的newHead。【其实这里的主要思想是,先把右节点压栈是为了保证出栈的节点(除了第一次出栈的)节点,即原二叉树的最右边的叶子节点)都会比当前双向链表的头newHead小,然后每次将newHead和small合并起来的操作就都是一样的了】
接着把下一个要遍历的节点temp设置为当前弹出节点small的左节点,这一步相当于后续会把当前弹出节点small的左子树转换为双向链表。
左子树转换完成后又会将右子节点为small的节点出栈,此时newHead不为空,执行对应的操作。
具体代码如下:(通过了牛客网的测试)
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
stack<TreeNode*> nodes;
TreeNode *newHead = NULL, *temp = pRootOfTree;
while(temp != NULL || !nodes.empty()) {
if(temp != NULL) {
//把所有右节点压栈
nodes.push(temp);
temp = temp->right;
}
else {
TreeNode *small = nodes.top();
nodes.pop();
if(newHead == NULL) {
newHead = small;
}
else {
small->right = newHead;
newHead->left = small;
newHead = small;
}
temp = small->left;
}
}
return newHead;
}
};