题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整结点指针的指向。
思路
- 对于二叉搜索树,采用中序遍历按照从小到大的顺序遍历二叉树的每一个结点,因此,只需要记录上一个结点lastNodeInList,将其和当前遍历的结点连接起来,便可实现转换。
- 初始化:需要一个共享的静态变量lastNodeInList,以便在两次递归调用中传递上一次的结果。初始值为null,因为head的上一个结点为null;
- 终止条件:考虑到终止时,lastNodeInList指向倒数第二个结点,current指向倒数第一个结点,此时整个双向链表已经完成,此时可以退出递归了;
- 循环过程:将lastNodeInList的下一节点为current,current的上一节点为lastNodeInList,更新lastNodeInList为current
- 特殊情况:
在初始情况下,lastNodeInList为null,此时无法将它下一结点置为current;
import datastructure.search.BiTreeNode;
public class Q27Convert {
public static BiTreeNode lastNodeInList=null;
public static BiTreeNode convert(BiTreeNode root){
convertNode(root);
BiTreeNode head=lastNodeInList;
while (head!=null&&head.leftChild!=null){
head=head.leftChild;
}
return head;
}
public static void convertNode(BiTreeNode node){
if (node==null)
return;
BiTreeNode current=node;
//对于双向链表的头结点,current.leftChild为null
if (current.leftChild!=null)
convertNode(current.leftChild);
current.leftChild=lastNodeInList;
//初始情况下lastNodeInList为null,要和一般情况分开
if (lastNodeInList!=null)
lastNodeInList.rightChild=current;
lastNodeInList=current;
//对于双向链表的尾结点的情况,此时倒数第一和倒数第二结点都已经连接了,整个双向链表已经形成
if (current.rightChild!=null)
convertNode(current.rightChild);
}
public static void traverse(BiTreeNode head){
System.out.println("From head to tail:");
while (head.rightChild!=null){
System.out.println(head.data);
head=head.rightChild;
}
System.out.println(head.data);
System.out.println("From tail to head:");
while (head.leftChild!=null){
System.out.println(head.data);
head=head.leftChild;
}
System.out.println(head.data);
}
public static void main(String[] args) {
int[] array={3,2,1,4,5};
BiTreeNode root=BiTreeNode.create(array);
BiTreeNode head=convert(root);
traverse(head);
}
}