题目:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表,要求不能创建任何新节点,只能调整树中结点指针的指向。最后输出排序后双向链表。
基本思想:
二叉树中每个节点都有两个指向子节点的指针。在双向链表中,每个节点也有两个指针,分别指向前一个节点和后一个节点。
二叉搜索树中,左子节点的值总是小于父节点的值,右子节点的值总是大于父节点的值。
在转换成双向链表时,原先指向左子节点的指针调整为链表中指向前一个节点的指针,原先指向右子节点的指针调整为链表中指向后一个节点的指针。
中序遍历树中的每一个节点,中序遍历算法是按照从小到大的顺序遍历二叉树的。
当遍历到根节点时,树看成三部分:值为10的节点、根节点值为6的左子树,根节点值为14的右子树,
值为10的节点将和它的左子树的最大一个节点(8)连接起来,同时它还将和右子树最小的节点(12)连接起来。
按照中序遍历的特点,当遍历转换到根节点(10)时,它的左子树已经转换成一个排序的链表了,并且处在链表中的最后一个节点是8,把8和10连接起来,最后一个节点成为了10,接着我们遍历转换右子树,将10和12连接起来。
至于如何转换左右子树,用递归。
#include <iostream>
using namespace std;
//二叉树结点定义
typedef struct BiTreeNode{
int data;
//左右孩子指针
struct BiTreeNode *lchild;
struct BiTreeNode *rchild;
}BiTreeNode,*BiTree;
//按先序序列创建二叉树
int CreateBiTree(BiTree &T)
{
int data;
//按先序次序输入二叉树中结点的值(一个字符),‘#’表示空树
cin>>data;
if(data == -1)
{
T = NULL;
}
else
{
T = (BiTree)malloc(sizeof(BiTreeNode));
T->data = data;//生成根结点
CreateBiTree(T->lchild);//构造左子树
CreateBiTree(T->rchild);//构造右子树
}
return 0;
}
void ConvertNode(BiTree pNode, BiTree * pLastNodeInList)
{
if(pNode == NULL)
return;
BiTree pCurrent = pNode;
//进行左子树的遍历
if (pCurrent->lchild != NULL)
ConvertNode(pCurrent->lchild, pLastNodeInList);
//做指针指向前面已经排好序的最后一个结点
pCurrent->lchild = *pLastNodeInList;
//如果最后一个结点不为空的话,那么就让排序的最后一个结点的右指针指向这棵树
if(*pLastNodeInList != NULL)
(*pLastNodeInList)->rchild = pCurrent;
//此时这个结点也就加入了排好序的链表中了
*pLastNodeInList = pCurrent;
//最后进行右子树的遍历
if (pCurrent->rchild != NULL)
ConvertNode(pCurrent->rchild, pLastNodeInList);
}
BiTree Convert(BiTree pRootOfTree)
{
BiTree pLastNodeInList = NULL;
ConvertNode(pRootOfTree, &pLastNodeInList);
// pLastNodeInList指向双向链表的尾结点,
// 我们需要返回头结点
BiTree pHeadOfList = pLastNodeInList;
while(pHeadOfList != NULL && pHeadOfList->lchild != NULL)
pHeadOfList = pHeadOfList->lchild;
return pHeadOfList;
}
//访问函数
void Visit(BiTree T)
{
if(T->data != -1)
cout<<T->data<<" ";
}
//先序遍历
void PreOrder(BiTree T)
{
if(T != NULL)
{
//访问根节点
Visit(T);
//访问左子结点
PreOrder(T->lchild);
//访问右子结点
PreOrder(T->rchild);
}
}
//输出双向链表
void PrintList(BiTree pRoot)
{
BiTree pNode = pRoot;
while(pNode != NULL)
{
cout<<pNode->data<<" ";
pNode = pNode->rchild;
}
cout<<endl;
}
void main()
{
BiTree T;
CreateBiTree(T);
cout<<"原二叉树为:";
PreOrder(T);
cout<<endl;
BiTree listHead = Convert(T);
cout<<"双向链表为:";
PrintList(listHead);
}