微软算法100题01 二叉搜索树转为双向链表

提高编程能力的最佳途径就是多写代码, 就让我们从现在开始吧!

 

1. 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
       10
      /    |
   6     14
 /   |     /  |
4   8   12  16
 转换成双向链表
4=6=8=10=12=14=16。

二叉查找树的特点:任意节点的左子树都要小于当前节点;右子树都要大于当前节点。
特点:查询某个值,需要的时间复杂度为O(lgN)

 

网上的解决方案大部分都是C的, 我给出一个JAVA的吧

我的思路:  如果要把一颗二叉树转换为已排序的双向链表,则在双向链表中,根节点的左子树必然在根节点的前面,根节点的右子树必然在根节点的后面,根节点的直接前缀节点必然为左子树中最大的节点根节点的直接后缀节点必然为右子树中最小的节点

1. 找到根节点的左子树,找到其最大节点,作为根节点的前缀节点

2. 找到根节点的右子树,找到其最小节点,作为根节点的后缀节点

3.如果左子树不是叶子节点,则用1和2 的逻辑递归处理该左子树

4.如果右子树不是叶子节点,则用1和2 的逻辑递归处理该右子树

 

 

  1 package com.rui.microsoft;
  2 
  3 /**
  4  * 
  5  * 
  6  * 把二元查找树转变成排序的双向链表
  7 题目:
  8 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
  9 要求不能创建任何新的结点,只调整指针的指向。
 10 10
 11 / \
 12 5  15
 13 / \ / \
 14 3 6 13 16
 15 转换成双向链表
 16 3=5=6=10=13=15=16
 17  */
 18 public class Test01 {
 19 
 20     public static void main(String[] args) {
 21         Test01 test = new Test01();
 22         Node root = test.initTree();
 23         Node head = test.convertToDoubleLink(root);
 24         while(null != head){
 25             System.out.print(" " + head.getValue());
 26             head = head.getRight();
 27         }
 28     }
 29     
 30     private boolean isLeaf(Node node){
 31         if(null == node.getLeft() && null == node.getRight()) return true;
 32         else return false;
 33     }
 34     
 35     private Node findMin(Node node){
 36         if(null == node) return null;
 37         if(null == node.getLeft()) return node;
 38         return findMin(node.getLeft());
 39     }
 40     
 41     private Node findMax(Node node){
 42         if(null == node) return null;
 43         if(null == node.getRight()) return node;
 44         return findMin(node.getRight());
 45     }
 46     
 47     public Node convertToDoubleLink(Node node){
 48         if(null == node) return null;
 49         
 50         Node head = findMin(node);
 51         
 52         //Find the node directly before current node in the double link
 53         Node leftNode = findMax(node.getLeft());
 54         
 55         //Find the node directly after current node in the double link
 56         Node rightNode = findMin(node.getRight());
 57         
 58         //Process left
 59         if(null != node.getLeft()){
 60             processLeftTree(node.getLeft(), node);
 61         }
 62         
 63         //Process right
 64         if(null != node.getRight()){
 65             processRightTree(node.getRight(), node);
 66         }
 67         
 68         //Relocate leftNode according to double link to the left side of current node
 69         if(null != leftNode){
 70             leftNode.setRight(node);
 71             node.setLeft(leftNode);
 72         }
 73         
 74         //Relocate rightNode according to double link to the right side of current node
 75         if(null != rightNode){
 76             rightNode.setLeft(node);
 77             node.setRight(rightNode);
 78         }
 79         
 80         return head;
 81     }
 82 
 83     private void processRightTree(Node right, Node node) {
 84         if(isLeaf(right)){
 85             right.setLeft(node);
 86             return;
 87         }
 88         convertToDoubleLink(right);
 89     }
 90 
 91     private void processLeftTree(Node left, Node node) {
 92         if(isLeaf(left)){
 93             left.setRight(node);
 94             return;
 95         }
 96         convertToDoubleLink(left);
 97     }
 98     
 99     private Node initTree(){
100         Node root = new Node();
101         root.setValue(10);
102         
103         Node node01 = new Node();
104         node01.setValue(5);
105         
106         Node node011 = new Node();
107         node011.setValue(3);
108         
109         Node node012 = new Node();
110         node012.setValue(6);
111         
112         node01.setLeft(node011);
113         node01.setRight(node012);
114         
115         root.setLeft(node01);
116 
117         Node node02 = new Node();
118         node02.setValue(15);
119         
120         Node node021 = new Node();
121         node021.setValue(13);
122         
123         Node node022 = new Node();
124         node022.setValue(16);
125         
126         node02.setLeft(node021);
127         node02.setRight(node022);
128         
129         root.setRight(node02);
130         return root;
131     }
132     
133     
134     class Node {
135         
136         private int value;
137         private Node left;
138         private Node right;
139         
140         /**
141          * @return the value
142          */
143         public int getValue() {
144             return value;
145         }
146         /**
147          * @param value the value to set
148          */
149         public void setValue(int value) {
150             this.value = value;
151         }
152         /**
153          * @return the left
154          */
155         public Node getLeft() {
156             return left;
157         }
158         /**
159          * @param left the left to set
160          */
161         public void setLeft(Node left) {
162             this.left = left;
163         }
164         /**
165          * @return the right
166          */
167         public Node getRight() {
168             return right;
169         }
170         /**
171          * @param right the right to set
172          */
173         public void setRight(Node right) {
174             this.right = right;
175         }
176     }
177 }

 

posted @ 2015-10-20 17:29  蟹粉小笼包  阅读(209)  评论(0编辑  收藏  举报