题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
题目分析
- 二叉树中每个节点都有两个指向子节点的指针;
- 在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点;
- 在将二叉树转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
概念
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; } };