题意:给定一棵二叉搜索树,将该二叉搜索树转化为一个排序的双向链表,要求只能调整树中节点指针的指向
分析:对二叉搜索树进行中序遍历,得到的序列就是有序的,如果在中序遍历的同时改变指针的指向,当中序遍历完成之后,就可以得到一个有序的双向链表。
按照上面的分析,将一棵二叉搜索树分为三部分,根节点(root),左子树(lchild),右子树(rchild),根据所需链表的需求,root节点应该跟lchild中节点最大的值相连,同时root节点还需要跟rchild中节点最小的值相连。当root节点跟lchild中节点的最大值相连时,lchild已被转化为一个有序的双向链表,然后再将root节点跟lchild连接起来,此时新的有序链表的长度就增加1了,之后再去遍历转换rchild,再将root节点和rchild中的最小值节点连接起来,对lchild、rchild的转换采用递归的方法。
核心:由于所采用的是中序遍历的方式,即采用下面的这种模式
void InOrder(BiTree pNode)
{
if(NULL == pNode)
return;
InOrder(pNode->lchild);
//.....processing
InOrder(pNode->rchild);
}
那么processing这部分应该怎么处理,从上面的分析可知这一步用来将root节点跟已经得到的有序双向链表连接起来,即有序双向链表的最后一个节点和root连接要互联,之后root节点就成为了有序双向链表的最后一个节点,然后在继续递归处理。
二叉树的定义参加二叉树的定义
具体的实现参见下面的代码:
#include "Binary.h"
void BiTreeToDLinkList(BiTree pRoot, BiTree *pLastNodeInList)
{
if(NULL == pRoot)
return;
//递归左子树
if(pRoot->lchild)
BiTreeToDLinkList(pRoot->lchild, pLastNodeInList);
//假设左子树已递归完成,左子树此时已是一个双向链表,*pLastNodeInList指向链表的最后一个节点,现在就需要完成当前节点和链接最后一个节点的链接工作,即pRoot与*pLastNodeInList的链接,在链接完成后不要忘记改当前链表的最后一个节点
pRoot->lchild = (*pLastNodeInList);
if((*pLastNodeInList) != NULL)
(*pLastNodeInList)->rchild = pRoot;
(*pLastNodeInList) = pRoot;
//递归右子树
if(pRoot->rchild)
BiTreeToDLinkList(pRoot->rchild, pLastNodeInList);
}
void ConvertTreeToLinkList(BiTree *pRoot)
{
if(NULL == *pRoot)
return;
BiTree pLastNodeInList = NULL;
BiTreeToDLinkList(*pRoot, &pLastNodeInList);
//完成转换之后得到的是链表的最后一个节点,现在通过最后一个节点,得到链表的头节点
(*pRoot) = pLastNodeInList;
while((*pRoot)->lchild != NULL)
{
*pRoot = (*pRoot)->lchild;
}
}
void PrintDLinkList(BiTree pRoot)
{
if(NULL == pRoot)
{
cout << "根节点为空,请输入有效数据" << endl;
return;
}
BiTree p = pRoot;
cout << "The nodes from left to right are:" << endl;
while(p)
{
cout << p->data << "\t";
if(NULL == p->rchild)
break;
p = p->rchild;
}
cout << endl;
//上面的循环跳出时,p指向链表的最后一个节点
cout << "The nodes from right to left are:" << endl;
while(p)
{
cout << p->data << "\t";
if(NULL == p->lchild)
break;
p = p->lchild;
}
cout << endl;
}
void Test(BiTree pRoot)
{
ConvertTreeToLinkList(&pRoot);
PrintDLinkList(pRoot);
}
void Test1()
{
BiTree pNode10 = NULL;
CreateBinaryTreeNode(&pNode10,10);
BiTree pNode6 = NULL;
CreateBinaryTreeNode(&pNode6,6);
BiTree pNode14 = NULL;
CreateBinaryTreeNode(&pNode14,14);
BiTree pNode4 = NULL;
CreateBinaryTreeNode(&pNode4,4);
BiTree pNode8 = NULL;
CreateBinaryTreeNode(&pNode8,8);
BiTree pNode12 = NULL;
CreateBinaryTreeNode(&pNode12,12);
BiTree pNode16 = NULL;
CreateBinaryTreeNode(&pNode16,16);
ConnectTreeNodes(pNode10, pNode6, pNode14);
ConnectTreeNodes(pNode6, pNode4, pNode8);
ConnectTreeNodes(pNode14, pNode12, pNode16);
Test(pNode10);
}
int main()
{
Test1();
return 0;
}