题目:二叉搜索树与双向链表
描述:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
注意:
1.要求不能创建任何新的结点,只能调整树中结点指针的指向。当转化完成以后,树中节点的左指针需要指向前驱,树中节点的右指针需要指向后继
2.返回链表中的第一个节点的指针
3.函数返回的TreeNode,有左右指针,其实可以看成一个双向链表的数据结构
4.你不用输出或者处理,示例中输出里面的英文,比如"From left to right are:"这样的,程序会根据你的返回值自动打印输出
示例:
输入: {10,6,14,4,8,12,16}
输出:From left to right are:4,6,8,10,12,14,16;From right to left are:16,14,12,10,8,6,4;
题目解析: 系统自动输入一颗二叉树,输出的时候将双向链表从左往右输出和从右往左输出,在输出过程中要确保答案的正确性。
解题思路:对于二叉搜索树来说,中序遍历输出的数值为升序排列。所以我们需要通过中序遍历去解决问题,因为输出的链表是从左往右输出,从左往右依次增大,我们按照正常思路来思考问题,就是将根节点的左(前)指向根节点左子树的最大值,将根节点的右(后)指向根节点右子树的最小值,若左子树或者右子树只有两层的话,直接将左子树或者右子树按照中序遍历输出即可。
采用递归操作解决问题,递归操作的条件为,当二叉树遍历遇到子节点为不存在的情况时就不会继续往下遍历,即终止本轮递归。总体思想是借用中序遍历,实现递归。
具体C++代码如下所示:
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
TreeNode* preNode = nullptr;
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
if(pRootOfTree == nullptr)
return nullptr;
Convert(pRootOfTree->right);//找到最右边的节点
if(preNode != nullptr){
pRootOfTree->right = preNode;
preNode->left = pRootOfTree;
}
preNode = pRootOfTree;
Convert(pRootOfTree->left);
return preNode;
}
}; 按照代码要求,首先执行的是最后一层的右结点,将右节点与右节点根结点之间构建连接,然后按照递归思想,一直循环执行即可完成目标输出。
另一种解法:在二叉树中,每个结点都有两个指向子结点的指针,双向链表中也存在,在搜索二叉树中左结点的值总是小于父结点的值,右结点的值总是大于父结点的值。在转换成排序双向链表时,原先指向左结点的指针调整为链表中指向前一个结点的指针,原先指向右结点的指针调整为链表中指向后一个结点的指针。
C++代码如下所示:
/*
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) {
TreeNode* pNode = NULL;
List(pRootOfTree,&pNode);
TreeNode* pHead = pNode;
while (pHead != NULL && pHead->left != NULL)
pHead = pHead->left;
return pHead;
}
void List(TreeNode* Root,TreeNode**pr){
if (Root == NULL)
return ;
TreeNode* pc = Root;
if(pc->left != NULL)//递归左子树
List(pc->left,pr);
pc->left = *pr;
if(*pr != NULL)
(*pr)->right = pc;
*pr = pc;
if(pc->right != NULL)
List(pc->right,pr);
}
};

京公网安备 11010502036488号