二叉树搜索树与双向链表
一:题目
二:思路
把二叉搜索树的值升序的打印出来,中序打印即可,但是此题不仅仅是有序的打印出二叉搜索树的值,而是要将其的结构也改变了,也就是说要改变节点间的指向,让其成为一个双向链表
我们在中序遍历的时候,会依次得到4 6 8 10 12 14 16,那我们在依次得到这些节点值的时候,将彼此之间进行链接即可
如图所示:
三:代码
class Solution {
//中序遍历 进行链接
void InOrderConvert(TreeNode* cur,TreeNode*& prev)
{
//cur为空return即可
if(cur==nullptr)
return;
//左子树递归
InOrderConvert(cur->left, prev);
//对cur和prev的链接
if(prev!=nullptr)
cur->left = prev;
if(prev!=nullptr)
prev->right = cur;
//链接完成 cur赋给了prev
//cur继续中序遍历得到下一个中序节点
prev = cur;
//右子树递归
InOrderConvert(cur->right, prev);
}
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
//二叉搜索树就是空树 则返回nullptr
if(pRootOfTree==nullptr)
return nullptr;
//为调用InOrderConvert函数创建参数
TreeNode* prev = nullptr;
//第一个参数就是根节点 第二个参数是为nullptr的prev
InOrderConvert(pRootOfTree, prev);
//走到这里 代表双向链表已经完成了
TreeNode* head = pRootOfTree;
//所以我们要找到双向链表的第一个元素
//也就是二叉搜索树的最小值
//即一直遍历左树 最后一个节点 即为最小节点
while(head->left)
{
head = head->left;
}
//返回
return head;
}
};
解释:
InOrderConvert的参数:
cur:当前正在处理的节点
prev:指向前一个处理过的节点的指针(引用传递,以便在递归调用间保持更新)
步骤:
递归处理左子树
InOrderConvert(cur->left, prev);
处理当前节点:
将当前节点的左指针(left)指向prev,将prev的右指针(right)指向当前节点,更新prev为当前节点
if(prev!=nullptr)
cur->left = prev;
if(prev!=nullptr)
prev->right = cur;
prev = cur;
递归处理右子树
InOrderConvert(cur->right, prev);
解释:中序遍历就是左根右,我们想做什么都是在 根 的这个方框里面做的,这道题是链接节点,若是按照下图,则变成了遍历打印,所以递归中序,前序,后序,都只是三个框的顺序不同罢了,当然也不要忘记空节点的判断,递归一定需要返回条件的!
这就变成了打印~