一、问题描述
输入一棵二叉搜索树,现在要将该二叉搜索树转换成一个排序的双向链表。而且在转换的过程中,不能创建任何新的结点,只能调整树中的结点指针的指向来实现。
查阅了相关内容,基本了解了这个问题的解析方法与思想。
DList BSTreeToList(BSTree tree)
{
if(tree == NULL)
return NULL;
//找到最左边的结点,即转换后链表的头结点
DLNode *head = FindLeftmostNode(tree);
BSNode *last_node = NULL;
//进行转换
ConvertNode(tree, &last_node);
return head;
}
BSNode* FindLeftmostNode(BSTree tree)
{
if(tree == NULL)
return NULL;
while(tree->left != NULL)
tree = tree->left;
return tree;
}
void ConvertNode(BSTree tree, BSNode **last_node)
{
if(tree == NULL)
return;
//对tree的左子树进行转换,last_node是转换后链表最后一个结点的指针
if(tree->left != NULL)
ConvertNode(tree->left, last_node);
//调整tree的left指针,指向上一个结点
tree->left = *last_node;
//调整指向最后一个结点,right指向下一个结点
if(*last_node != NULL)
(*last_node)->right = tree;
//调整指向最后链表一个结点的指针
*last_node = tree;
//对tree的右子树进行转换,last_node是转换后链表最后一个结点的指针
if(tree->right != NULL)
ConvertNode(tree->right, last_node);
}
//搜索二叉树->双链表
void BinaryTreeToDoublyList(BiTree &root)
{
if (root == NULL)
return;
if (root->lChild == NULL && root->rChild == NULL)
return;
BiNode* left = root->lChild;
BiNode* right = root->rChild;
BinaryTreeToDoublyList(left);
BinaryTreeToDoublyList(right);
//找到左子树的最大结点
if(left)
{
while(left->rChild)
{
left = left->rChild;
}
left->rChild = root;
root->lChild = left;
}
if (right)
{
//找到右子树的最大结点
while(right->lChild)
{
right = right->lChild;
}
right->lChild = root;
root->rChild = right;
}
}
void BinaryTreeToDoublyListMain(BiTree &root)
{
if (root == NULL)
return;
BinaryTreeToDoublyList(root);
//root指向双向链表头
if (root->lChild)
root = root->lChild;
}
void Convert(BinaryTreeNode* pNode,BinaryTreeNode** pLastNodeInList)
{
if(pNode==NULL)
return;
BinaryTreeNode* pCurrent=pNode;
//左子树转换,遍历到左子树的叶子结点
if(pCurrent->m_pLeft!=NULL)//遍历左子树
Convert(pCurrent->m_pLeft,pLastNodeInList);
pCurrent->m_pLeft=*pLastNodeInList;
if((*pLastNodeInList)!=NULL)
(*pLastNodeInList)->m_pRight=pCurrent;
*pLastNodeInList=pCurrent;
//右子树转换
if(pCurrent->m_pRight!=NULL)//遍历右子树
Convert(pCurrent->m_pRight,pLastNodeInList);
}
BinaryTreeNode* Convert(BinaryTreeNode* pRoot)
{
BinaryTreeNode* pLastNodeInList=NULL;//指向双向链表的尾结点
Convert(pRoot,&pLastNodeInList);//转换排序二叉树为双向链表
//求双向链表的头结点
BinaryTreeNode* pHeadOfList=pLastNodeInList;
while(pHeadOfList!=NULL&&pHeadOfList->m_pLeft!=NULL)
pHeadOfList=pHeadOfList->m_pLeft;
return pHeadOfList;
}