题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题思路1
我们可以中序遍历二叉搜索树,并将遍历到的结点保存起来,这样得到的结点的值是从小到大排序的,然后再修改指针关系。
这样做法的缺点是需要申请额外的存储空间。
代码实现
/*
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){
if(!pRootOfTree)return NULL;
TreeNode *reHead;
vector <TreeNode *> arr;
convert(pRootOfTree,arr);
reHead=arr[0],arr[0]->left=NULL;
arr[arr.size()-1]->right=NULL;
for(int i=0;i<arr.size()-1;i++){
arr[i]->right=arr[i+1];
arr[i+1]->left=arr[i];
}
return reHead;
}
void convert(TreeNode *root,vector <TreeNode *> &arr){
TreeNode *ptr=root;
if(ptr->left)convert(ptr->left,arr);
arr.push_back(ptr);
if(ptr->right)convert(ptr->right,arr);
}
};
运行时间:2ms
占用内存:480k
解题思路2
我们以中序的顺序遍历结点,当遇到当前结点没有左子树的时候将其保存,并继续中序遍历,当遇到下一个结点时修改该结点的left
指针,让其指向上一结点,并让上一结点的right
指针指向该结点。
重复这一过程,直到所有的结点都被遍历到,则所有的指针修改完成。
最终,我们只需要找到头结点并返回即可。
代码实现
/*
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){
if(!pRootOfTree)return NULL;
TreeNode *reHead,*last=NULL,*tmp=pRootOfTree;
con(pRootOfTree,&last);
while(tmp->left){
tmp=tmp->left;
}
reHead=tmp;
return reHead;
}
void con(TreeNode *root,TreeNode **last){
TreeNode *tmp=root;
if(tmp->left)con(tmp->left,last);
tmp->left=*last;
if(*last)(*last)->right=tmp;
*last=tmp;
if(tmp->right)con(tmp->right,last);
}
};
运行时间:3ms
占用内存:376k