码迷,mamicode.com
首页 > 其他好文 > 详细

剑指offer 二叉搜索树与双向链表

时间:2017-09-04 13:13:51      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:变量   des   原因   scribe   top   创建   数组   调整   root   

题目描述

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
 
思路:迭代版本:
核心思想是中序遍历,头结点需要单独设置flag变量进行初始化。
if(!s.empty()){
                if(flag == 1){
                    head = s.top();
                    cur = s.top();
                    s.pop();
                    cur -> left = pre;
                    pre -> right = cur;
                    pre = pre -> right;
                    flag = 0;
                }
                else{  
                    cur = s.top();
                    s.pop();
                    cur -> left = pre;
                    pre -> right = cur;
                    pre = pre -> right;
                 }
                cur = cur -> right;
            }

开始写成这样导致错误:数组越界/堆栈溢出。

根本原因在于pre开始初始化为nullptr,不能直接使用pre -> right = cur;这样就是对空指针进行操作。

所以需要改成pre = cur,因为接下来cur会等于栈的下一个元素,pre就在cur的前面了,

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree){
        TreeNode* head = pRootOfTree;
        TreeNode* pre = nullptr;
        TreeNode* cur = pRootOfTree;
        stack<TreeNode*> s;
        int flag = 1;
        while(cur != nullptr || !s.empty()){
            while(cur != nullptr){
                s.push(cur);
                cur = cur -> left;
            }
            if(!s.empty()){
                if(flag == 1){
                    head = s.top();
                    cur = s.top();
                    s.pop();
                    pre = cur;
                    flag = 0;
                }
                else{  
                    cur = s.top();
                    s.pop();
                    cur -> left = pre;
                    pre -> right = cur;
                    pre = pre -> right;
                 }
                cur = cur -> right;
            }
        }
        return head;
    }
};

思路2:递归版本实现。

递归的将左子树实现双链表,然后将left链表链接到root上,然后递归的实现右子树,将root链接到右子树上。

/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    TreeNode* helper(TreeNode* root){
      if(root == nullptr){
            return nullptr;
       }
       TreeNode* leftNode = helper(root -> left);//返回头结点
       TreeNode* leftHead = leftNode;
        while(leftNode != nullptr && leftNode -> right != nullptr){
            leftNode = leftNode -> right;
        }
       if(leftNode != nullptr){
           leftNode -> right = root;
           root -> left = leftNode;
       }
       TreeNode* rightNode = helper(root -> right);
       if(rightNode != nullptr){
           root -> right = rightNode;
           rightNode -> left = root;
       }
       
        
       return leftHead != nullptr ? leftHead : root;
    }
    TreeNode* Convert(TreeNode* pRootOfTree){
        if(pRootOfTree == nullptr){
            return nullptr;
        }
        return helper(pRootOfTree);
    }
};

 

 

 

 

剑指offer 二叉搜索树与双向链表

标签:变量   des   原因   scribe   top   创建   数组   调整   root   

原文地址:http://www.cnblogs.com/dingxiaoqiang/p/7472839.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!