问题:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,
要求不能创建任何新的结点,只调整指针的指向 。
10
/ \6 14
/ \ / \
4 8 12 16
转换成 4->6->8->10->12->14->16
问题来源:
本题是微软的面试题
问题分析:
一般与树有关的题目都可以用递归的思路来解决,本题我们也可以考虑用此思路来解决。
思路一:
每到一个节点时准备调整以该节点为根节点的子树(先调整其左子树,将左子树转换成一个排好序的左子链表,再调整其右子树,将其转换成右子链表,最后链接左子链表的最右端、当前节点、右子链表的最左端)。从树的根节点开始递归调整所有的节点。
思路二:
采用数的中序遍历整棵树。按这种方式比较小的节点会先被访问。如果我们每访问一个节点,假设之前访问过的节点已经调整成一个排序的双向链表,我们再把当前访问的阶段加入到其链表末尾。当所有的节点访问结束后,整棵树便变成了双向链表。
代码实现(Java):
public class Node<T extends Comparable<T>> {
private T data;
private Node<T> lNode;
private Node<T> rNode;
public Node(T data){
this.setData(data);
this.setlNode(null);
this.setrNode(null);
}
/**
* @return the data
*/
public T getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(T data) {
this.data = data;
}
/**
* @return the lNode
*/
public Node<T> getlNode() {
return lNode;
}
/**
* @param lNode the lNode to set
*/
public void setlNode(Node<T> lNode) {
this.lNode = lNode;
}
/**
* @return the rNode
*/
public Node<T> getrNode() {
return rNode;
}
/**
* @param rNode the rNode to set
*/
public void setrNode(Node<T> rNode) {
this.rNode = rNode;
}
}
/**
* @ClassName: BTree
* @Description: This class describe the binary tree
* @author xiangmin@cn.ibm.com
* @date Mar 2, 2015 2:01:53 PM
*
*/
public class Tree<T extends Comparable<T>> {
public Node<T> root = null;
/**
* @Title: addNode
* @Description: This method used to add a new node into the tree
* @param @param data
* @return void
* @throws
*/
public void addNode(T data){
Node<T> node = new Node<T>(data);
if(root == null){
root = node;
} else {
Node<T> parent = root;
Node<T> cur = root;
boolean isLeft=true;
while(cur != null)
{
parent=cur;
if(data.compareTo(cur.getData()) < 0) {
isLeft = true;
cur = cur.getlNode();
} else {
isLeft=false;
cur = cur.getrNode();
}
}
if(isLeft) {
parent.setlNode(node);
} else
parent.setrNode(node);
}
}
/**
*
* @Title: display
* @Description: display all the nodes in tree
* @param @param node
* @return void
* @throws
*/
public void display(Node<T> node){
if(node != null){
display(node.getlNode());
System.out.print(node.getData() + "-->");
display(node.getrNode());
}
}
}
public class List<T extends Comparable<T>> {
/**
*
* @Title: append
* @Description: append two list
* @param @param node1
* @param @param node2
* @param @return
* @return Node<T>
* @throws
*/
public Node<T> append(Node<T> node1,Node<T> node2)
{
if(node1==null)
return node2;
if(node2==null)
return node1;
Node<T> tail=node1;
while(tail.getrNode()!=null) {
tail=tail.getrNode();
}
tail.setrNode(node2);
node2.setlNode(tail);
return node1;
}
public void display(Node<T> node){
while(node != null){
System.out.print(node.getData() + "\t");
node = node.getrNode();
}
}
}
public interface TreeToLinkList<T extends Comparable<T>> {
public Node<T> convert(Node<T> root);
}
public class Test {
/**
* @param args
*/
public static void main(String[] args) {
Tree<Integer> tree=new Tree<Integer>();
tree.addNode(49);
tree.addNode(25);
tree.addNode(55);
tree.addNode(10);
tree.addNode(51);
tree.addNode(65);
tree.display(tree.root);
System.out.println();
TreeToLinkList<Integer> solution = new TreeToLinkListImpl1<Integer>();
Node<Integer> node = solution.convert(tree.root);
List<Integer> list = new List<Integer>();
list.display(node);
TreeToLinkList<Integer> solution2 = new TreeToLinkListImpl2<Integer>();
Node<Integer> node2 = solution2.convert(tree.root);
List<Integer> list2 = new List<Integer>();
list2.display(node2);
}
}
思路一代码:
public class TreeToLinkListImpl1<T extends Comparable<T>> implements TreeToLinkList<T>{
/* (non-Javadoc)
* <p>Title: convert</p>
* <p>Description: </p>
* @param tree
* @see Algorithm.Test.T001_TreeToLinkList.TreeToLinkList#convert(Algorithm.Test.T001_TreeToLinkList.Tree)
*/
@Override
public Node<T> convert(Node<T> root) {
List<T> list = new List<T>();
if(root != null){
Node<T> left = convert(root.getlNode());
Node<T> right = convert(root.getrNode());
root.setlNode(null);
root.setrNode(null);
left = list.append(left, root);
left = list.append(left, right);
return left;
} else {
return null;
}
}
}
思路二代码:
/**
* @ClassName: TreeToLinkListImpl1
* @Description: The class implements the algorithm that convert the tree to link list
* @author xiangmin@cn.ibm.com
* @date Mar 2, 2015 4:24:31 PM
*
*/
public class TreeToLinkListImpl2<T extends Comparable<T>> implements TreeToLinkList<T>{
public Node<T> firstListNode;
/* (non-Javadoc)
* <p>Title: convert</p>
* <p>Description: </p>
* @param tree
* @see Algorithm.Test.T001_TreeToLinkList.TreeToLinkList#convert(Algorithm.Test.T001_TreeToLinkList.Tree)
*/
@Override
public Node<T> convert(Node<T> root) {
inOrder(root);
return this.firstListNode;
}
public void inOrder(Node<T> root){
List<T> list = new List<T>();
if(root.getlNode()!=null){
inOrder(root.getlNode());
}
this.firstListNode = list.append(this.firstListNode, new Node<T>(root.getData()));
if(root.getrNode()!=null){
inOrder(root.getrNode());
}
}
}