将二叉搜索树转换成一个排序的双向链表。
注意:要求不能创建任何新的结点,只能调整树中结点指针的指向,也就是left当prev,right当next。
在二叉搜索树中,每个结点都有两个分别指向其左、右子树的指针,左子树结点的值总是小于父结点的值,右子树结点的值总是大于父结点的值。在双向链表中,每个结点也有两个指针,它们分别指向前一个结点和后一个结点。所以这两种数据结构的结点是一致,二叉搜索树和双向链表,只是因为两个指针的指向不同而已,完全可以通过改变其指针的指向来实现二者的转换。
思路:
找到二叉搜索树中左子树的最右边的节点,使其与根节点连成双向关系
找到二叉搜索树中右子树的最左边的节点,使其与根节点连成双向关系
struct serchTreeNode
{
serchTreeNode(int data)
:_data(data)
, pLeft(NULL)
, pRight(NULL)
{}
int _data;
serchTreeNode* pLeft;
serchTreeNode* pRight;
};
serchTreeNode* serchTreeToList(serchTreeNode* pRoot)
{
//空树
if (pRoot == NULL)
return NULL;
//二叉搜索树只有根节点
if (pRoot->pLeft == NULL&&pRoot->pRight == NULL)
return pRoot;
serchTreeNode* pLeftRoot = serchTreeToList(pRoot->pLeft);//转换左子树
serchTreeNode* pLeftNode = pLeftRoot;
while (pLeftNode != NULL&&pLeftNode->pRight != NULL)//找到左子树的最右边的节点(左子树中最大)
{
pLeftNode = pLeftNode->pRight;
}
//如果左子树链表存在,则将根节点与左子树最右节点连成双向关系
if (pLeftRoot)
{
pLeftNode->pRight = pRoot;
pRoot->pLeft = pLeftNode;
}
serchTreeNode* pRightRoot = serchTreeToList(pRoot->pRight);//转换右子树
serchTreeNode* pRightNode = pRightRoot;
while (pRightNode!=NULL&&pRightNode->pLeft!=NULL)//找到右子树最左边的节点(右子树中最小)
{
pRightNode = pRightNode->pLeft;
}
//如果右子树链表存在,则将根节点与右子树最左节点连成双向关系
if (pRightRoot)
{
pRightNode->pLeft = pRoot;
pRoot->pRight = pRightNode;
}
if (pLeftRoot)
return pLeftRoot;
else
return pRightRoot;
}