程序员代码面试指南(左程云)读书笔记
第三章
将搜索二叉树转换成双向链表
对于二叉树的节点来说,有本身的值域,有指向左孩子和右孩子的两个指针:对双向链表来说,有本身的值域,有指向上一节点和下一阶节点的指针。在结构上还是有相似的地方的,现在有一棵搜索二叉树,请将其转换为一个有序的双向链表。
方法一:
用队列等容器收集二叉树中中序遍历的结果的方法,时间复杂度为O(N),额外空间复杂度为O(N),过程如下:
1,生成一个队列,记为queue,按照二叉树中序遍历的顺序,将每个节点放入queue中。
2,从queue中依次弹出节点,并按照弹出的顺序重连所有节点即可。
import java.util.LinkedList;
import java.util.Queue;
//搜索二叉树转换成双向链表
public class TreeToArray {
public static void main(String[] args) {
}
public static Node convert1(Node head){
if(head==null){
return null;
}
Queue<Node> queue =new LinkedList<Node>();
inOrderQueue(head,queue);
if(queue.isEmpty()){
return head;
}
head=queue.poll();
Node pre=head;
pre.left=null;
Node cur=null;
while(!queue.isEmpty()){
cur=queue.poll();
pre.right=cur;
cur.left=pre;
pre=cur;
}
pre.right=null;
return head;
}
private static void inOrderQueue(Node head, Queue<Node> queue) {
if(head==null){
return ;
} inOrderQueue(head.left, queue);
queue.offer(head);
inOrderQueue(head.right, queue);
}
}
class Node{
public int value;
public Node left;
public Node right;
public Node(int data){
this.value=data;
}
}
方法二:利用递归函数,时间复杂度为O(N),额外空间复杂度为O(h),h为二叉树的高,过程如下:
1,实现递归函数process。他的功能就是将一棵搜索二叉树转换为一个结构有点特殊的有序双向链表。这个双向链表尾结点的right指针指向该双向链表的头节点,函数最终返回这个链表的尾节点。
2,通过process过程得到的双向链表是尾节点的right指针指向头节点的结构。所以,最终需要将尾节点的right指针设置为null来让双向链表还原。
//递归不用容器方法
public static Node process(Node head){
if(head==null){
return head;
}
Node leftE=process(head.left);
Node rightE=process(head.right);
Node leftS=leftE!=null?leftE.right:null;
Node rightS=rightE!=null?rightE.right:null;
if(leftE!=null && rightE!=null){
leftE.right=head;
head.left=leftE;
head.right=rightS;
rightS.left=head;
rightE.right=leftS;
return rightE;
}else if(leftE!=null){
leftE.right=head;
head.left=leftE;
head.right=leftS;
return head;
}else if(rightE!=null){
head.right=rightS;
rightS.left=head;
rightE.right=head;
return rightE;
}else{
head.right=head;
return head;
}
}