二元查找树转变成排序的双向链表

来源:互联网 发布:阿里云购买的域名在哪 编辑:程序博客网 时间:2024/05/22 10:22

声明:题目来自: http://blog.csdn.net/v_JULY_v/archive/2010/11/17/6015165.aspx   JULY整理了100道微软等公司的面试题目,我想先不看答案:http://blog.csdn.net/v_JULY_v/archive/2011/01/10/6126406.aspx  自己先做一遍。

 

题目:

 

1.  把二元查找树转变成排序的双向链表
 题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
   10
  /  /
 6    14
 / /  / /
4  8 12 16
 转换成双向链表
4=6=8=10=12=14=16。
 首先我们定义的二元查找树 节点的数据结构如下:
 
 struct BSTreeNode
{
  int m_nValue; // value of node
  BSTreeNode *m_pLeft; // left child of node
  BSTreeNode *m_pRight; // right child of node
};

 

思路:

 

看一下输出的双向链表,他的顺序和二元查找树的先序遍历的顺序是一致的,所以一开始我的思路就是用先序遍历来解这个问题。既然是递归,那么问题肯定能转换成,要把 节点parent之下(包括节点parent)所代表的二叉树转变成双向链表,我们认为parent的left child 和 right child都已经是转换好的 双向链表了,所以伪代码是:

 

preOrderTransform(Parent A)

{

      preOrderTransform(Left Child of Parent A);

      preOrderTransform(Right Child of Parent A);

 

      把 1)左儿子中最大节点, 2)当前Parent节点 ,3)还有 右儿子的最小节点  链接起来

}

 

直观的思路就是 让preOderTransform(leftChild) 返回左儿子中最大的节点;让preOrderTransform(rightChild)返回右儿子中最小的节点。但是 问题是: 当parent A所管理的数转换好以后,它可以作为祖父节点B 的左字数,也有可能作为祖父节点B 的右字数,如果作为B的左子树,B需要知道A的最大节点,但是处理A的 preOrderTransform(Parent A) 目前并不知道它麾下最大的节点是谁,除非1) 它向右遍历 (因为这时候A麾下已经是双向链表,我们可以通过 node=node->m_right 一直找到最右边的,也就是最大的节点);或者2) 我们想办法让A 记住自己的最小和最大节点。

 

我下面的代码采用了“记住”的方法:

 

代码:

class BSTreeNode{
 int m_nValue;
 BSTreeNode m_left;
 BSTreeNode m_right;
 
 BSTreeNode(int value){
  m_nValue = value;
 }
}

 

public class BinaryTree2DoubleLink {
 
 
  
   static class Result{
    BSTreeNode head;
    BSTreeNode tail;
   
    public Result(BSTreeNode head, BSTreeNode tail){
     this.head = head;
     this.tail = tail;
    }
   }
  
   BSTreeNode buildTree(){
   
    BSTreeNode root = new BSTreeNode(10);
    root.m_left = new BSTreeNode(6);
    root.m_right = new BSTreeNode(14);
   
    BSTreeNode node = root.m_left;
    node.m_left = new BSTreeNode(4);
    node.m_right = new BSTreeNode(8);
   
    node = root.m_right;
    node.m_left = new BSTreeNode(12);
    node.m_right = new BSTreeNode(16);
   
    return root;
   }
  
  
   //
   Result preOrder(BSTreeNode node){
   
        Result result = new Result(node, node);
   
        if(node == null ){
              return result;
         }
   
         //let's make left child a double linked list
         //leftResult remember the head and tail of the new double linked list
         Result leftResult  = preOrder(node.m_left);
   
   
         //let's make right child a double linked list
         Result rightResult = preOrder(node.m_right);
   
          //link current node with the tail node of left child linked list
          if(leftResult.tail != null){  //注意边界条件
                  leftResult.tail.m_right = node;
          }
          node.m_left = leftResult.tail;
      
          //link current node with the head node of right child linked list
          if(rightResult.head != null){
                 rightResult.head.m_left = node;
          }
          node.m_right = rightResult.head;
      
          //modify the result after merge current node with both it's left child and right child
      
          if(leftResult.head != null){   //注意边界条件
                 result.head = leftResult.head;
          }
      
           if(rightResult.tail != null){
                 result.tail = rightResult.tail;
           }
         
           return result;

   }
  
   Result transform(BSTreeNode root){
   
    BSTreeNode head = null;
   
    Result result =  preOrder(root);
    //the order of double linked list is actually the order of pre-order traverse
   
    return result;
   
   }
  
   void print(Result result){
   
    //print from head
    BSTreeNode node = result.head;
    while(node != null){
     System.out.format("%2d ", node.m_nValue);
     node = node.m_right;
    }
    System.out.println();
   
    node = result.tail;
    while(node != null){
     System.out.format("%2d ", node.m_nValue);
     node = node.m_left;
    }
    System.out.println();
   
   }
  
      public static void main(String[] args){
      
       BinaryTree2DoubleLink app = new BinaryTree2DoubleLink();
       BSTreeNode root = app.buildTree();
      
       Result result = app.transform(root);
       app.print(result);
      
      }
}

 

 

 

原创粉丝点击