1.把二元查找树转变成排序的双向链表(树)
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
看到这题 ,想到一个动画 ,最后要得到的双向链表无非是要将这棵二叉树串成有序的一串。从二维变成一维。
相像一个从树的叶结点一层层向上一层的结点中插入的过程。
即由
10
/ \
6 14
/ \ / \
4 8 12 16
先变成:
10
/ \
4 - 6 - 8 12 - 14 - 16
再变成:
4 - 6 - 8 - 10 - 12 - 14 - 16
这就是最后要的结果了。
用递归,从最下面一层开始向上一层插入。要做的就是修改指针的指向。
把4跟8分别插入到6的前跟后的时候,6的左指针不用修改,右指针也不用修改。只需要将4的右指针指向6, 再将8的左指针指向6即可。
再将4-6-8看作整体,插入到它们的上一层也就是10。这时候 ,10的左指针指向6,而它应该指向8才对,所以这一步插入的时候要先将10的左指针右移直到找到4-6-8中最右边的结点为止,将10的左指针指向它(这个例子中是8)即可。
对于12-14-16的组合同理,将10的右指针左移,直到找到最左边的结点为12,指向它。
最后得到的输出就是想要的结果了。
最核心的转换代码如下。
void insert_pro(tnode* root,tnode* newa){
//每次将左孩子对父节点做前插的时候,考虑到待插入的是一个已经链好的链表,需要找到其尾结点
while(newa->getrigh())
newa=newa->getrigh();
newa->setright(root);
root->setleft(newa);
}
void insert_next(tnode* root,tnode* newa){
while(newa->getleft())
newa=newa->getleft();
root->setright(newa);
newa->setleft(root);
}
void bitree2bilist(tnode* root){
tnode* tp;
if(tp=root->getleft()){
bitree2bilist(tp);
insert_pro(root,tp);// insert the node to root's left
}
if(tp=root->getrigh()){
bitree2bilist(tp);
insert_next(root,tp);// insert the node to root's right
}