ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-10-20 18:31:09  阅读:334  来源: 互联网

标签:right cur 右子 nullptr 36 二叉 链表 prev 节点


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

思路:中序遍历+双指针
class Solution {
public:
    Node* treeToDoublyList(Node* root) {
        if(root==nullptr) return root;
        stack<Node*> stk;
        while(root!=nullptr){
            stk.push(root);
            root=root->left;
        }
        Node* prev=nullptr,*head;
        while(stk.size()){
            Node* cur=stk.top();
            stk.pop();
            if(prev==nullptr)
                head=cur;
            else{
                prev->right=cur;
                cur->left=prev;
            }
            prev=cur;
            if(cur->right) {
                cur=cur->right;
                //注意要遍历所有的左子树
                while(cur!=nullptr){
                    stk.push(cur);
                    cur=cur->left;
                }
            }
        }
        prev->right=head;
        head->left=prev;
        return head;
    }
};

时间复杂度 O(N) N是二叉树的节点数

空间复杂度 O(N)

Morris中序遍历

流程如下:

  1. 如果cur为空,停止遍历
  2. 如果cur不为空:
    1. 如果cur的左节点为空,打印cur值,然后让cur指向右子节点
    2. 如果cur有左子节点,则让左子节点找到最右边的结点pre
      1. 如果pre的右子节点为空,让pre的右子节点指向cur,即pre->right=cur,然后cur指向左子节点,即cur=cur->left
      2. 如果pre的右子节点不为空,则让它指向空,即pre->right=nullptr,然后输出cur的值,并将cur指向右子节点,即cur=cur->right

具体可以看下二叉树的Morris中序和前序遍历

先序遍历和中序遍历只是访问结点的时机不同,先序遍历在步骤2访问左子树之前访问根节点,中序遍历在访问左子树后访问右子树前访问根节点,具体步骤如下:

  1. 如果cur为空,停止遍历
  2. 如果cur不为空:
    1. 如果cur的左节点为空,然后让cur指向右子节点
    2. 如果cur有左节点,则让左子节点找到最右边的结点pre
      1. 如果pre的右子节点为空,让pre的右子节点指向cur,打印cur值,然后cur指向左子节点
      2. 如果pre的右子节点不为空,则让它指向空,然后指向右子结点
class Solution {
public:
    Node* treeToDoublyList(Node* root) {
        if(root==nullptr) return root;
        Node* prev=nullptr,*cur=root,*head;
        while(cur!=nullptr){
            if(cur->left==nullptr){
                if(prev==nullptr){
                    head=cur;
                }else{
                    prev->right=cur;
                }
                cur->left=prev;
                prev=cur;
                cur=cur->right;
            }else{
                Node* preTree=cur->left;
                while(preTree->right!=nullptr&&preTree->right!=cur){
                    preTree=preTree->right;
                }
                if(preTree->right==nullptr){
                    preTree->right=cur;
                    cur=cur->left;
                }else{
                    preTree->right=nullptr;
                    prev->right=cur;
                    cur->left=prev;
                    prev=cur;
                    cur=cur->right;
                }
            }
        }
        head->left=prev;
        prev->right=head;
        return head;
    }
};

时间复杂度 O(n)

空间复杂度 O(1)

标签:right,cur,右子,nullptr,36,二叉,链表,prev,节点
来源: https://blog.csdn.net/qq_44038801/article/details/120872307

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有