题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路:由于要求转换后的链表是排序的,而中序遍历算法的特点就是按照从小到大的顺序遍历二叉树每个节点,因此采用中序遍历树中每个节点,当遍历到根节点时,把树分为3部分:根节点、左子树和右子树,通过递归把左、右子树都转换成排序双向链表后,把左子树中最大的节点、根节点、右子树中最小的节点链接起来,整棵二叉搜索树就转换成了排序双向链表。
核心代码如下:
struct BinaryTreeNode{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList);
BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree){
//pLastNodeInList指向双向链表的尾节点
BinaryTreeNode* pLastNodeInList = nullptr;
ConvertNode(pRootOfTree, &pLastNodeInList);
//最后需要返回双向链表的头结点
BinaryTreeNode* pHeadOfList = pLastNodeInList;
while(pHeadOfList != nullptr && pHeadOfList->m_pLeft != nullptr)
pHeadOfList = pHeadOfList->m_pLeft; //向前移动
return pHeadOfList;
}
void ConvertNode(BinaryTreeNode* pNode, BinaryTreeNode** pLastNodeInList){
if(pNode == nullptr)
return;
BinaryTreeNode* pCurrent = pNode;
if(pCurrent->m_pLeft != nullptr)
ConvertNode(pCurrent->m_pLeft, pLastNodeInList); //遍历转换左子树
pCurrent->m_pLeft = *pLastNodeInList; //左子树中最大的节点为当前链表的尾节点
if(*pLastNodeInList != nullptr)
(*pLastNodeInList)->m_pLeft = pCurrent; //将根节点加入到链表中
*pLastNodeInList = pCurrent; //更新根节点为当前链表的尾节点
if(pCurrent->m_pRight != nullptr)
ConvertNode(pCurrent->m_pRight, pLastNodeInList); //遍历转换右子树
}