关于剑指offer上“二叉搜索树与双向链表”题的理解

来源:互联网 发布:ae cc for mac 编辑:程序博客网 时间:2024/06/05 01:07

题目描述:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。


一、递归的思路

对于函数TreeNode* Convert(TreeNode* root),传入的是需要转换的二叉树的头结点,返回的是已经转换好的双向链表的头结点。从root结点来看,以递归的思路就是将左孩子和右孩子做黑盒处理,left = Convert(root->left)返回的就是以左孩子为根节点的树已经转化好的双向链表的头结点,right = Convert(root->right)返回的就是以右孩子为根节点的树已经转化好的双向链表的头结点,只要left和right不为空,使用left找到左孩子双向链表的最后一个结点node,将node,root,right一连接,问题解决!


步骤:

1、根节点为root,递归root的左孩子,将左子树构成双向链表,并返回链表头结点left

2、使用left头结点遍历到左子树双链表的最后一个结点node

3、如果左子树链表不为空,将node和root连接起来

4、同理将右子树构成双向链表,并返回链表头结点right

5、如果右子树链表不为空,将root和right连接起来

6、如果left不为空,返回left,否则返回root


代码如下:

/*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* root)    {        if(root == NULL){            return NULL;        }        if(root->left == NULL && root->right == NULL){            return root;        }        //1、根节点为root,递归root的左孩子,将左子树构成双向链表,并返回链表头结点left        TreeNode* left = Convert(root->left);        TreeNode* node = left;        //2、使用left头结点遍历到左子树双链表的最后一个结点node        while(node != NULL && node->right != NULL){            node = node->right;        }//while        //3、如果左子树链表不为空,将node和root连接起来        if(left != NULL){            node->right = root;            root->left = node;        }        //4、同理将右子树构成双向链表,并返回链表头结点right        TreeNode* right = Convert(root->right);        //5、如果右子树链表不为空,将root和right连接起来        if(right != NULL){            root->right = right;            right->left = root;        }        //6、如果left不为空,返回left,否则返回root        return left == NULL?root:left;    }};


二、非递归思路

按照二叉树中序遍历非递归的思路


代码:

struct TreeNode{    int val;    TreeNode* left;    TreeNode* right;};//对比,二叉树的非递归中序遍历求法void inorder(TreeNode* root){    //非递归版中序遍历    if(NULL == root){        return;    }    stack<TreeNode*> data;    TreeNode* node = root;    while(node!=NULL || !data.empty()){        while(node != NULL){            data.push(node);            node = node->left;        }//while        if(!data.empty()){            node = data.top();            data.pop();            cout<<node->val<<endl;            node = node->right;        }    }//while    return;}TreeNode* Convert(TreeNode* root){    if(NULL == root){        return NULL;    }    if(root->left == NULL && root->right == NULL){        return root;    }    stack<TreeNode*> data;    TreeNode* node = root;    TreeNode* pre = NULL;  //用于保存中序遍历序列的上一个结点    bool isFirst = true;    while(node != NULL || !data.empty()){        while(node != NULL){            data.push(node);            node = node->left;        }        node = data.top();        data.pop();        if(isFirst){            root = node;   //将中序遍历中的第一个结点记为root            pre = root;            isFirst = false;        }else{            pre->right = node;            node->left = pre;            pre = node;        }        node = node->right;    }    return root;}


牛客网题目地址:

https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&rp=2&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking


阅读全文
0 0
原创粉丝点击