剑指 Offer 36. 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的循环双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
为了让您更好地理解问题,以下面的二叉搜索树为例:
我们希望将这个二叉搜索树转化为双向循环链表。链表中的每个节点都有一个前驱和后继指针。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
特别地,我们希望可以就地完成转换操作。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继。还需要返回链表中的第一个节点的指针。
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode() : val(0), left(nullptr), right(nullptr) {}
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
int n=-1;
TreeNode *create(vector<int> c){
TreeNode* node;
n++;
if(n>=c.size()){return NULL;}
else{
if(c[n]==0) node=nullptr;
else{
node=new TreeNode(c[n]);
node->left=create(c);
node->right=create(c);
}
}
return node;
}
TreeNode *pre, *head;
void dfs(TreeNode* cur){
if (cur==nullptr) return;
dfs(cur->left);
if(pre!=nullptr) pre->right=cur;
else head=cur;
cur->left=pre;
pre=cur;
dfs(cur->right);
}
TreeNode* treeToDoublyList(TreeNode* root){
if(root==nullptr) return nullptr;
dfs(root);
head->left=pre;
pre->right=head;
return head;
}
vector<int> DFS(TreeNode* &node){
vector<int> v;
if(node==nullptr) return v;
queue<TreeNode*> q;
q.push(node);
while(!q.empty()){
TreeNode* root = q.front();
q.pop();
v.push_back(root->val);
if(root->left!=nullptr) q.push(root->left);
if(root->right!=nullptr) q.push(root->right);
}
return v;
}
int main(){
vector<int> tree;
tree.push_back(4);
tree.push_back(2);
tree.push_back(1);
tree.push_back(0);
tree.push_back(0);
tree.push_back(3);
tree.push_back(0);
tree.push_back(0);
tree.push_back(5);
tree.push_back(0);
tree.push_back(0);
TreeNode*node=create(tree);
TreeNode* head = treeToDoublyList(node);
TreeNode* now=head;
printf("%d ", now->val);
now=now->right;
while(now!=head){
printf("%d ", now->val);
now=now->right;
}
return 0;
}