这是从一位仁兄那里看到的一道题,题目如下:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
看到这个题呢,一个很自然的想法就是递归,对一棵树的左右子树分别递归,生成两个排序的双向链表,然后把根和右子树插入到左子树中,这就是一个整体的思路,代码如下:
#include"BSTree2lb.h"
#include<stdio.h>
struct BSTreeNode* Sort(struct BSTreeNode*tree)
{
if(tree==NULL)
return NULL;
struct BSTreeNode*left=Sort(tree->m_pLeft);//左排序
struct BSTreeNode*right=Sort(tree->m_pRight);//右排序
tree->m_pLeft=NULL;
tree->m_pRight=NULL;
left=Insert(left,tree);//将根插入左侧链表
left=Insert(left,right);//将右侧链表插入左侧链表
return left;
}
//将beinserted插入到insert中
struct BSTreeNode* Insert(struct BSTreeNode*insert,struct BSTreeNode*beinserted)
{
if(beinserted==NULL)
return insert;
if(insert==NULL)
return beinserted;
struct BSTreeNode*temp=NULL;
struct BSTreeNode*head=NULL;//合并后的头部
struct BSTreeNode*ip=NULL;//ip为insert的前一项,若为空则insert为首项
if(insert->m_nValue<beinserted->m_nValue)
head=insert;
else head=beinserted;
head->m_pLeft=NULL;
while(1)
{
if(beinserted==NULL)//若无插入项则退出
break;
if(ip!=NULL&&insert==NULL)//若ip指向最后一项
{
ip->m_pRight=beinserted;
beinserted->m_pLeft=ip;
break;
}
if(beinserted->m_nValue<=insert->m_nValue)//若插入条件成立
{
if(ip==NULL)//若inser为首项
{
ip=beinserted;
temp=beinserted->m_pRight;
beinserted->m_pRight=insert;
beinserted->m_pLeft=NULL;
insert->m_pLeft=beinserted;
beinserted=temp;
}
else
{
temp=beinserted->m_pRight;//beinserted插入ip,insert之间
ip->m_pRight=beinserted;
beinserted->m_pLeft=ip;
beinserted->m_pRight=insert;
insert->m_pLeft=beinserted;
ip=beinserted;//下一循环新的状态
beinserted=temp;
}
}
else
{
ip=insert;
insert=insert->m_pRight;
}
}
return head;
}
void test_bst()
{
struct BSTreeNode data[7]={
{10,data+1,data+2},
{6,data+3,NULL},
{14,data+5,NULL},
{4,NULL,data+4},
{8,NULL,data+6},
{12,NULL,NULL},
{16,NULL,NULL}};
struct BSTreeNode*r=Sort(data);
while(r->m_pRight!=NULL)
{
printf("%d=",r->m_nValue);
r=r->m_pRight;
}
printf("%d\n",r->m_nValue);
}
如上,Sort()是排序函数,Insert()是将一个链表插入到另一个链表中,test_bst()是测试函数。程序目前为止没有问题,欢迎指出里面的bug