面试题27:二叉搜索树与双向链表
题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。比如输入下图的二叉搜索树,则输出转换之后的排序双向链表。
分析:从二叉搜索树到有序序列的转换分析,首先二叉搜索的定义:若树不为空则子树也为二叉搜索树,且左子树比根小,右子树比根大。所以递增顺序为:左->根->右。这个顺序好像在哪里见过,即二叉树的中序遍历结果。所以当时我的思路是这样的,先中序遍历二叉树然后将结果保存在一个队列中,然后在出队建立链表关系即改变指针方向。写完代码后发现答案其实可以更简洁,即在遍历的过程中改变指针。把我的代码中入队的代码改为改变指针的代码即可。
但是第一次看答案的代码还是没看明白,后来画图后才真正的理解。先上代码:
BinaryTreeNode* Convert(BinaryTreeNode* pRoot)
{
BinaryTreeNode *pLastNode = NULL;//指向尾结点
ConvertNode(pRoot,&pLastNode);
BinaryTreeNode *pHead = pLastNode;
while(pHead != NULL && pHead->pLeft != NULL)
{
pHead = pHead->pLeft;
}
return pHead;
}
void ConvertNode(BinaryTreeNode* pNode,BinaryTreeNode **pLast)
{
if(pNode == NULL)
{
return ;
}
BinaryTreeNode *pCurrent = pNode;
if(pCurrent->pLeft != NULL)
{
ConvertNode(pCurrent->pLeft,pLast);
}
pCurrent->pLeft = *pLast;
if(*pLast != NULL)
{
(*pLast)->pRight = pCurrent;
}
*pLast = pCurrent;
if(pCurrent->pRight != NULL)
{
ConvertNode(pCurrent->pRight,pLast);
}
}
直到认认真真的把这棵二叉搜索树带入进去才弄明白,上图是分析过程。