新的思路
新思路没有超时,效果还行,如果想看我的旧思路记得拉到底下!本来不懂怎么做了,直到用中序遍历输出了一遍值,所以多试试总是有好处的hhhhh
题目解读:给一个二叉搜索树,将二叉搜索树转换成一个“树链表”,将值从大到小排列下去。
思路:从大到小排列值 -> 对二叉搜索树进行中序遍历就可以得到从大到小排列的值的列表 -> 将列表的这种形式用树替代即可
具体方法:
- 涉及到更改父节点和子节点的关系,我们需要借助一个prev指针来记住父节点。
- 第一个节点的记录最好用一个head,这样以来,prev也可以等于head
- 迭代方式:prev->right = root, prev = root
- 记得把每一个root->left = NULL
代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* head = new TreeNode;
TreeNode* prev = new TreeNode;
bool flag = true;
TreeNode* convertBiNode(TreeNode* root) {
TreeNode* temp = new TreeNode(-1);
dfs(root);
return head->right;
}
void dfs(TreeNode* root){
if(!root)
return;
dfs(root->left);
// flag只用来初始化一次
if(flag){
head->right = root;
prev = head;
flag = false;
}
// 迭代prev
prev->right = root;
prev = root;
root->left = NULL;
dfs(root->right);
}
};
复杂的旧思路(超时了有点尴尬)
给大家看一下可怕的最后一个测试例子(图没有截完整,还有很长……)
我画了图(我需要的结果图和题目图的差别)经过观察发现,这不就是AVL树的右旋吗?通过右旋可以交换子节点和父节点,且由于二叉搜索树的特殊性质,交换完正好是从大到小的顺序,于是就有了以下代码。
旧思路的代码
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* convertBiNode(TreeNode* root) {
//递归超时了
if(!root)
return NULL;
if(root->left)
{
root->left = convertBiNode(root->left);
root = rightSingleRotation(root);
root->left = NULL;
}
if(root->right)
{
root->right = convertBiNode(root->right);
}
return root;
}
TreeNode* rightSingleRotation(TreeNode* root)
{
if(!root)
return NULL;
TreeNode* newRoot = root->left;
root->left = newRoot->right;
newRoot->right = root;
return newRoot;
}
};