数据结构BinaryTree实例(七):二叉树转成双向链表

来源:互联网 发布:led灯 知乎 编辑:程序博客网 时间:2024/06/07 16:47

       输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

    二分查找树的中序遍历即为升序排列,问题就在于如何在遍历的时候更改指针的指向。一种简单的方法时,遍历二分查找树,讲遍历的结果放在一个数组中,之后再把该数组转化为双链表。如果题目要求只能使用O(1)内存,则只能在遍历的同时构建双链表,即进行指针的替换用递归的方法来解决,假定每个递归调用都会返回构建好的双链表,可把问题分解为左右两个子树。由于左右子树都已经是有序的,当前节点作为中间的一个节点,把左右子树得到的链表连接起来即可。

     

/**  

*@Title: TreeToList.java

*@Package binarytree

*@Description: TODO

*@author peidong 

*@date 2017-4-25 上午8:20:28

*@version V1.0  

*/

packagebinarytree;

 

/**

 * @ClassName: TreeToList

 * @Description: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。

 *              要求不能创建任何新的结点,只调整指针的指向。

 * @date 2017-4-25 上午8:20:28

 * 

 */


publicclass TreeToList {

       /**

        *

       * @ClassName: ListNode

       * @Description: 构建二叉树结点,同时也是双链表结点

       * @date 2017-4-25 上午8:32:34

       *

        */

       public static class ListNode{

              public int data;

              public ListNode left;

              public ListNode right;

             

              public ListNode(int data){

                     this.data = data;

                     left = null;

                     right = null;

              }

       }

      

       /**

        *

       * @Title: append

       * @Description: 合并两个链表

       * @param @param a

       * @param @param b

       * @param @return   

       * @return ListNode   

       * @throws

        */

       public static ListNode append(ListNode a,ListNode b){

              //边界条件判断

              if(a == null){

                     return b;

              }

              if(b == null){

                     return a;

              }

             

              //获得两个链表的最后一个元素

              ListNode aLast = a.left;

              ListNode bLast = b.left;

             

              //连接两个链表

              aLast.right = b;

              b.left = aLast;

              bLast.right = a;

              a.left = bLast;

             

              return a;

       }

      

       public static ListNodetreeToList(ListNode root){

              //边界判断

              if (root == null) {

                     return null;

              }

 

              // 递归子树,此处要弄清楚,为什么递归在前而转换在后

              ListNode aList =treeToList(root.left); // 左子树

              ListNode bList =treeToList(root.right); // 右子树

 

              // 将根节点转换为循环链表

              root.left = root;

              root.right = root;

             

              //合并并排序,合并之后左子树为头结点,右子树为尾结点

              aList = append(aList, root);  //合并左子树与父结点

              aList = append(aList, bList); //合并左子树与右子树

             

              //返回头结点

              return aList;

       }

      

       /**

        *

       * @Title: treeInsert

       * @Description: 递归构建二叉平衡树

       * @param @param root

       * @param @param data   

       * @return void   

       * @throws

        */

       public static void treeInsert(ListNoderoot, int data){

              if(data <= root.data){

                     if(root.left != null){   //如果存在左子树

                            treeInsert(root.left,data);   //左子树递归调用

                     }else {

                            root.left = newListNode(data);  //不存在则构建左子树

                     }

              }else{

                     if(root.right != null){

                            treeInsert(root.right,data);  //如果存在右子树,则右子树递归

                     }else{

                            root.right = newListNode(data);  //不存在则构建右子树

                     }

              }

       }

      

       /**

        *

       * @Title: printBinaryTree

       * @Description: 中序遍历二叉平衡树

       * @param @param root   

       * @return void   

       * @throws

        */

       public static voidprintBinaryTree(ListNode root){

              //边界条件

              if(root == null){

                     return;

              }

             

              //递归左子树

              printBinaryTree(root.left);

              //输出节点数据

              System.out.print(Integer.toString(root.data)+"");

              //输出右子树

              printBinaryTree(root.right);

       }

      

       public static void printList(ListNodehead){

             

              ListNode cur = head;

             

              while(cur != null){

                     System.out.print(Integer.toString(cur.data)+"");

                     cur = cur.right;

                     if(cur == head){

                            break;

                     }

              }

             

              System.out.println();

       }

      

       /**

        *@Title: main

        *@Description: 测试用例

        *@param @param args   

        *@return void   

        *@throws

        */

       public static void main(String[] args) {

              // TODO Auto-generated method stub

        //构建根节点

              ListNode root = new ListNode(6);

             

              //插入数据构成二叉平衡树

              treeInsert(root, 7);

              treeInsert(root, 3);

              treeInsert(root, 9);

              treeInsert(root, 1);

              treeInsert(root, 2);

              treeInsert(root, 10);

              treeInsert(root, 8);

              treeInsert(root, 4);

              treeInsert(root, 5);

             

              //输出二叉树

              System.out.println("二叉平衡树:");

              printBinaryTree(root);

              //换行

              System.out.println();

             

              //输出循环双向链表

              System.out.println("循环链表:");

              //将二叉树转换成循环链表

              ListNode head =treeToList(root);

              //输出循环链表

              printList(head);

       }

 

}

阅读全文
0 0