📅  最后修改于: 2023-12-03 15:25:16.103000             🧑  作者: Mango
#将二叉树转换为线程二叉树 |第 2 组(高效)
##介绍 在二叉树中,每个节点有左右子树,中序遍历二叉树时,需要遍历左子树->当前节点->右子树。线索二叉树是对二叉树进行了修改,每个节点增加两个指针,一个指向其前一个节点,一个指向其后一个节点。这样中序遍历时,可以通过前后节点的指针跳过左右子树的遍历,直接访问所有节点。
本组高效的实现了将普通二叉树转换为线索二叉树的算法,时间复杂度为O(n),空间复杂度为O(1)。
##代码片段
ThreadedBinaryTreeNode* ConvertToThreadedBinaryTree(BinaryTreeNode* root)
{
if (root == nullptr)
return nullptr; //空树
//中序遍历树,当前节点为node,前一个节点为pre
BinaryTreeNode* node = root;
ThreadedBinaryTreeNode* threadedNode = nullptr;
ThreadedBinaryTreeNode* pre = nullptr;
while (node != nullptr)
{
//左子树还没处理
if (node->left != nullptr)
{
//找到左子树中最右边的节点,即前序节点
BinaryTreeNode* rMostNode = node->left;
while (rMostNode->right != nullptr && rMostNode->right != node)
{
rMostNode = rMostNode->right;
}
//前序节点的右指针指向当前节点
if (rMostNode->right == nullptr)
{
rMostNode->right = node;
}
//进入左子树
node = node->left;
}
//左子树处理完成
else
{
//创建当前节点的线索节点
threadedNode = new ThreadedBinaryTreeNode(node->data);
//线索节点的左指针指向前序节点或者空
threadedNode->left = pre;
//如果前序节点不存在,则当前节点为第一个节点
if (pre == nullptr)
threadedNode->IsLeftThread = true; //标记为叶子节点
//前序节点的右指针指向当前线索节点
if (pre != nullptr && pre->right == nullptr)
{
pre->IsRightThread = true; //标记为叶子节点
pre->right = threadedNode;
}
pre = threadedNode;
//进入右子树
node = node->right;
}
}
//返回线索树的根
return threadedNode;
}
##算法分析 通过中序遍历对二叉树进行遍历,每个节点之间需要建立前/后节点指针。对于左子树还未处理的节点,进入其左子树进行处理,找到左子树中最右边的节点,将其右指针指向当前节点。对于左子树处理完成的节点,创建当前节点的线索节点,线索节点的左指针指向前序节点或者空,前序节点的右指针指向当前节点的线索节点。处理完右子树后,返回线索树的根。
时间复杂度为O(n),空间复杂度为O(1)。
##总结 线索二叉树改变了节点的指向关系,使得遍历时能够跳过左右子树的遍历,直接访问所有节点。本组实现的转换算法效率高,适用于大数据量的二叉树。