题目:
输入一颗二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,职能调整树中结点指针的指向。如下图所示:
由于要求转换之后的链表是排好序的,我们可以中序遍历树中的每一个结点,这回死因为中序遍历算法的特点是按照从小到大的顺序遍历二叉树的每一个节点。当遍历到根结点时,我们可以把书=树看成三部分:值为10的结点,根结点值为6的左子树,根结点值为14的右子树。根据排序链表的定义,值为10的结点将和它的左子树的最大一个结点(即值为8的结点)连接起来,同时它还将和右子树最小的结点(即值为12的结点)连接起来。
按照中序遍历的顺序,当我们遍历到根结点(值为10的结点)时,他的左子树已经转换为一个排序的链表了,并且处在链表中的最后一个结点是当前最大的结点。我们把值为8的结点和根结点连接起来,此时链表中的最后一个结点就是10了。接下来去便利右子树,并把根结点和柚子树章最小的结点连接起来。可以采用递归的想法。
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode *m_pLeft;
BinaryTreeNode *m_pRight;
};
BinaryTreeNode* Convert(BinaryTreeNode* pRootOfTree)
{
BinaryTreeNode*pLastNodeInList = NULL;
ConvertNode(pRootOfTree, &pLastNodeInList);
//pLastNodeInList指向双向链表的尾结点
//返回头结点
BinaryTreeNode* pHeadOfList = pLastNodeInList;
while (pHeadOfList != NULL&&pHeadOfList->m_pLeft != NULL)
pHeadOfList = pHeadOfList->m_pLeft;
return pHeadOfList;
}
void ConvertNode(BinaryTreeNode*pNode, BinaryTreeNode**pLastNodeInList)
{
if (pNode == NULL)
return;
BinaryTreeNode*pCurrent = pNode;
if (pCurrent->m_pLeft != NULL)
ConvertNode(pCurrent->m_pLeft, pLastNodeInList);
pCurrent->m_pLeft = *pLastNodeInList;
if (*pLastNodeInList != NULL)
(*pLastNodeInList)->m_pRight = pCurrent;
*pLastNodeInList = pCurrent;
if (pCurrent->m_pRight != NULL)
ConvertNode(pCurrent->m_pRight, pLastNodeInList);
}