剑指 Offer 36. 二叉搜索树与双向链表

剑指 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;//pre为空时,指定头节点
    cur->left=pre;//链表逆序
    pre=cur;//pre按顺序移动
    dfs(cur->right);
    //当递归终止时,pre指向尾节点
}
//时间复杂度O(N) 空间复杂度O(N)
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);
    // vector<int> vx = DFS(node);//用于判断树是否创建成功
    // for(int i=0; i<vx.size(); i++){
    //     printf("%d ", vx[i]);
    // }
    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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值