题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
题目分析
- 二叉树中每个节点都有两个指向子节点的指针;
- 在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点;
- 在将二叉树转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
概念
1、二叉搜索树:二叉搜索树(英语:Binary Search Tree),也称二叉查找树、有序二叉树(英语:ordered binary tree),排序二叉树(英语:sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
- 任意节点,如果左子树不为空,则左子树上所有结点的值均小于它的根结点的值;
- 任意节点,如果右子树不为空,则右子树上所有结点的值均大于它的根结点的值;
- 任意节点的左、右子树也分别为二叉查找树;
- 没有键值相等的节点。
解题思路
由于二叉搜索树的特点,可以看出其中序遍历的结果是从小到大访问节点的,正好符合链表有序的要求,所以可以借助中序遍历的过程来完成二叉树到链表的转换过程,可以采用递归进行处理。
每次在递归遍历的时候设置一个pre,记录中序遍历时当前访问节点(node)的前一个节点,然后将当前节点的左指针指向pre,然后如果pre节点不为空则将pre的右节点指向当前节点,由此就形成了一个双向链表的前后指针。每次递归重复这两步,则可以形成一个完整的双向链表。最后一步就是双向链表已经构建完成了,而题目要求返回双向链表,则往前遍历找到双向链表的头返回即可。
代码
/*
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 == NULL )
return NULL;
help( pRootOfTree );
while( pre->left != NULL )
pre = pre->left;
return pre;
}
TreeNode* pre = NULL;
void help( TreeNode* node )
{
if( node == NULL )
return;
if( pre == NULL && node->left == NULL )
pre = node;
help( node->left );
if( pre != NULL && pre != node )
{
// pre为上一个节点,node为当前节点
pre->right = node;
node->left = pre;
pre = node;
}
help(node->right);
return;
}
};