今日碎碎念: 太难了~真的太难了
题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题分析
知识点
1.二叉搜索树
二叉搜索树特点可以反映在中序遍历上
a.若任意结点的左子树不空,则左子树上所有结点的值均不大于它的根结点的值。
b. 若任意结点的右子树不空,则右子树上所有结点的值均不小于它的根结点的值。
c.任意结点的左、右子树也分别为二叉搜索树。
2.线索二叉树
在二叉树的结点上加上线索的二叉树称为线索二叉树,对二叉树以某种遍历方式(如先序、中序、后序或层次等)进行遍历,使其变为线索二叉树的过程称为对二叉树进行线索化。
3.双向链表
思路
1.递归+遍历
先中序遍历树,用一个数组存储,再遍历一遍数组改变指针成双向。
2.递归
中序遍历的基础上处理指针,把左边变成链表,把根节点链接上去,再把右结点变成链表连接上去。具体的步骤在代码注释中~
代码实现
递归版
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
// 全局变量pre指向链表的最后一个结点,开始的时候链表还没有建立,所以是nullptr
TreeNode *pre=nullptr;
TreeNode* Convert(TreeNode* pRootOfTree)
{
//如果树为空,则返回空
if(!pRootOfTree) return nullptr;
// 1.将左子树构造成双链表,并返回链表头节点
TreeNode *head=Convert(pRootOfTree->left);
// 2.若链表头节点为空(即左子树为空),则链表头节点为当前根节点
if(head==nullptr)
head=pRootOfTree;
// 3.将root追加到左子树链表
// 3.1 root向左指向左子树的最后一个节点
pRootOfTree->left=pre;
// 3.2 若左子树不为空,则左子树的最后一个节点可以指向root
if(pre!=nullptr)
pre->right=pRootOfTree;
// 4.更新pre指向
pre=pRootOfTree;
// 5.将右子树构造成双链表
Convert(pRootOfTree->right);
return head;
}
};
结果