问题:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表,
要求不能创建任何新的结点,只调整指针的指向 。
10
/ \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 [email protected] * @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 [email protected] * @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()); } } }