題意
將一棵二叉搜索樹的結點按照從小到大的順序構建成一個雙向鏈表,要求不能創建新的節點。
思路
- 首先很容易想到對二叉樹的中序遍歷可以得到升序的結點序列。
- 其次,維護一個頭結點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;
}