1.题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
2.我的题解
使用数组保存中序遍历的结果,然后顺序更改指针。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
vector<TreeNode *> v;
void inOrder(TreeNode * root){
if(!root)return;
inOrder(root->left);
v.push_back(root);
inOrder(root->right);
}
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
v.clear();
inOrder(pRootOfTree);
for(int i=1;i<v.size();i++){
v[i]->left=v[i-1];
v[i-1]->right=v[i];
}
return v.empty()?NULL:v[0];
}
};
3.别人的题解
仅使用两个额外节点,一个记录链表头(head
),一个记录前一个节点(pre
)。在中序遍历的过程中,改变节点的指针:将当前节点左孩子指向pre
,pre
的右孩子指向当前节点。
空间复杂度:O(1)
下面是一个示例:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
TreeNode * pre=NULL;
TreeNode * head=NULL;
void inOrder(TreeNode * root){
if(!root)return;
inOrder(root->left);
root->left=pre;
if(pre)pre->right=root;
pre=root;
if(!head)head=root;
inOrder(root->right);
}
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
inOrder(pRootOfTree);
return head;
}
};
另有一写法可能更易读一些:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
TreeNode * left=NULL;
TreeNode * right=NULL;
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree)return NULL;
Convert(pRootOfTree->left);
if(!right){
left=pRootOfTree;
right=pRootOfTree;
}
else{
right->right=pRootOfTree;
pRootOfTree->left=right;
right=right->right;
}
Convert(pRootOfTree->right);
return left;
}
};
4.总结与反思
(1)演示程序 (.NET4.5)
链接:https://pan.baidu.com/s/1ZrbssQqfsRJ3wt4bOs2TEQ
提取码:71i0
(2)C#窗体应用程序绘图、Timer
。