题目:
输入一颗二叉搜素树,将该树转换成一个排序的双向链表.要求不能创建新的结点,只能
调整树中结点指针的指向.
思想:
10
/ \
6 4---------------->4==6==8==10==12==14==16
/\ /\
4 8 12 16
我们可以中序遍历整棵树。按照这个方式遍历树,比较小的结点先访问。
如果我们每访问一个结点,假设之前访问过的结点已经调整成一个排序双向链表,
我们再把调整当前结点的指针将其链接到链表的末尾。当所有结点都访问过之后,
整棵树也就转换成一个排序双向链表了。
#include<stdio.h>
#include<stdlib.h>
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
} ;
struct ListNode
{
int m_nValue;
ListNode* pNext;
};
void convertNode(BinaryTreeNode*,BinaryTreeNode**);
BinaryTreeNode* convert(BinaryTreeNode* pRootOfTree)
{
BinaryTreeNode* pLastNodeInList=NULL;
convertNode(pRootOfTree,&pLastNodeInList);
//得到双向链表的头结点
BinaryTreeNode* pHeadOfList=pLastNodeInList;
while(pHeadOfList!=NULL&&pHeadOfList->m_pLeft!=NULL)
pHeadOfList=pHeadOfList->m_pLeft;
return pHeadOfList;
}
void convertNode(BinaryTreeNode* pNode,BinaryTreeNode** pLastNodeInList)
{
if(pNode==NULL)
return;
BinaryTreeNode* pCurrent=pNode;
//转换左子树
if(pCurrent->m_pLeft!=NULL)
convertNode(pCurrent->m_pLeft,pLastNodeInList);
//把当前结点放到双向链表中
pCurrent->m_pLeft=*pLastNodeInList;
if(*pLastNodeInList!=NULL)
(*pLastNodeInList)->m_pRight=pCurrent;
*pLastNodeInList=pCurrent;
//转换右子树
if(pCurrent->m_pRight!=NULL)
convertNode(pCurrent->m_pRight,pLastNodeInList);
}
BinaryTreeNode* createTree(BinaryTreeNode* pRoot)
{
int data;
scanf("%d",&data);
if(data!=-1)
{
pRoot=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
if(pRoot==NULL)
exit(0);
pRoot->m_nValue=data;
pRoot->m_pLeft=createTree(pRoot->m_pLeft);
pRoot->m_pRight=createTree(pRoot->m_pRight);
return pRoot;
}
return NULL;
}
void printNode(BinaryTreeNode* pTree)
{
if(pTree==NULL)
return;
if(pTree->m_pRight!=NULL)
{
printf("%d\t",pTree->m_nValue);
pTree=pTree->m_pRight;
printNode(pTree);
}
else
printf("%d",pTree->m_nValue);
}
int main()
{
int num;
while(scanf("%d",&num)!=EOF)
{
BinaryTreeNode* pNode;
BinaryTreeNode* pTree=createTree(pNode);
BinaryTreeNode* pList = convert(pTree);
printNode(pList);
}
return 0;
}
结果见上