版权声明:本文为博主原创文章,转载请标明原文地址,谢谢 ^_^ https://blog.csdn.net/xiaoquantouer/article/details/77963378
题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
一、递归的思路
对于函数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;
}
牛客网题目地址: