题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路
因为这是一个二叉搜索树,并且要求将其变成排序的双向链表,这正符合二叉树的中序遍历思路,当我们遍历到根节点的时候,左子树已经排好序,我们要就是将左子树的最大节点与根节点相连,至于如何实现左子树的排序,用pre保存上一个节点,中序遍历到当前节点cur时,就将pre->right = cur,cur->left = pre,然后进行更新pre。
AC代码
#include <iostream>
using namespace std;
struct TreeNode
{
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL)
{
}
};
//先序创建
TreeNode *Create_tree()
{
TreeNode *T;
int val;
cin >> val;
if (val == 0) //叶子结点用0标记
return NULL;
else
{
T = new TreeNode(val);
T->left = Create_tree();
T->right = Create_tree();
}
return T;
}
//先序遍历
void pre_print(TreeNode *T)
{
if (T)
{
cout << T->val << " ";
pre_print(T->left);
pre_print(T->right);
}
}
class Solution
{
public:
TreeNode *Convert(TreeNode *pRootOfTree)
{
if (pRootOfTree == NULL)
return NULL;
TreeNode *p = NULL; //因为左子树的最后一个左孩子的左指针须为空
convert(pRootOfTree, p);
//找到最左子树的最左孩子,然后返回
while (pRootOfTree->left)
{
pRootOfTree = pRootOfTree->left;
}
return pRootOfTree;
}
void convert(TreeNode *cur, TreeNode *&pre)
{
if (cur == NULL)
return;
convert(cur->left, pre);
cur->left = pre;
if (pre)
pre->right = cur; //将上一个节点指向当前节点,比如是5--> 6
pre = cur; //更新上一个节点
convert(cur->right, pre);
}
};
int main()
{
TreeNode *root = Create_tree();
pre_print(root);
cout << endl;
Solution so;
TreeNode *res = so.Convert(root);
cout << res->val << endl;
while (res)
{
cout << res->val << " ";
res = res->right;
}
return 0;
}
/*
8 6 5 0 0 7 0 0 10 9 0 0 11 0 0
8 6 5 7 10 9 11
5
5 6 7 8 9 10 11
*/
总结
- 存在问题,对二叉树的线索化不熟悉啊=-=