题意
将一棵二叉搜索树的结点按照从小到大的顺序构建成一个双向链表,要求不能创建新的节点。
思路
- 首先很容易想到对二叉树的中序遍历可以得到升序的结点序列。
- 其次,维护一个头结点head,和一个始终指向当前最后一个结点的prev。
因此每在第一步得到一个节点,就把它插入到prev的后面,并更新prev。
注意,树中最左下的结点是第一个遍历到的结点,此时应令其为头结点,即head = cur。 - 遍历完成后,将头尾结点串起来。
代码
/*
// Definition for a Node.
class Node {
public:
int val;
Node* left;
Node* right;
Node() {}
Node(int _val) {
val = _val;
left = NULL;
right = NULL;
}
Node(int _val, Node* _left, Node* _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
Node* head, prev;
void solve(Node* root) {
if(!root)
return ;
solve(root->left);
if(prev == NULL) // 此时node是最左下的结点
head = root;
else
prev->right = root;
root->left = prev;
prev = root; // 令prev指向最后的结点
solve(root->right);
}
Node* treeToDoublyList(Node* root) {
if(root == NULL)
return NULL; //链表题目一定要考虑空的情况
solve(root, ans); // 中序遍历 + 构建双链表
head->left = prev; // 头结点的前驱指向尾结点
prev->right = head; // 尾结点的后继指向头结点
return head;
}