题目:输入一棵二叉树,将该二叉树转换成一个排序的双向链表。要求不能创建任何新的节点,只能调整树中节点指针的指向。
在二叉搜索树中,左子节点的值总是小于父节点的值,右子节点的值总是大于父节点的值,因此,我们在转换成排序双向链表时,原先指向左子节点的指针调整为指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
由于要求转换之后的链表时排好序的,我们可以中序遍历树中的每一个节点,因为中序遍历的特点是按照从小到大的顺序遍历二叉树的每一个节点,当遍历到根节点的时候,我们把树看成三部分:值为10的节点,根节点为6的左子树,根节点为14的右子树。
按照中序遍历的顺序,当我们遍历转换到根节点时,它的左子树已经转换成一个排序的链表了,并且处在链表中的最后一个节点就是当前值最大的节点。我们把左子树的最右节点和根节点连接起来此时链表中的最后一个节点就是根节点了。接着我们再去遍历右子树,并把根节点和右子树的最左节点链接,遍历右子树的过程就和之前是一样的了。
所以,我们很自然就想到用递归求解。
typedef struct BinaryTreeNode
{
int _value;
BinaryTreeNode* _left;
BinaryTreeNode* _right;
}Node;
void ConvertNode(Node* pNode, Node** pLast)
{
if (pNode == NULL)
return;
Node* pCur = pNode;
if (pCur->_left != NULL)
ConvertNode(pCur->_left, pLast);
pCur->_left = *pLast;
if (*pLast != NULL)
(*pLast)->_right = pCur;
*pLast = pCur;
if (pCur->_right != NULL)
ConvertNode(pCur->_right, pLast);
}
Node* Convert(Node* root)
{
if (root == NULL)
return NULL;
Node* pLast = NULL;
ConvertNode(root, &pLast);
//此时pLast指向双向链表的尾节点,我们需要返回头节点
Node* Head = pLast;
while (Head && Head->_left)
{
Head = Head->_left;
}
return Head;
}