15.输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4260432.html 

声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。

题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换。

题目分析:

  注:二叉排序树的中序遍历结果是升序排序的,因此将该树转换为它的镜像之后,该树的中序遍历结果应是降序排序的。

  一、递归实现:

  这种方式相对比较好实现,传入树的根节点,当节点不为空时,交换根节点的左右孩子,再递归交换左右子树的左右孩子。

  算法实现:

1     private void exchangeRecursive(Node root){
2         if(root!=null){    
3             swap(root);         //交换根节点的左右子树
4             exchangeRecursive(root.left);  //递归交换左子树
5             exchangeRecursive(root.right); //递归交换右子树
6         }
7     }

  二、循环方式实现:

  这种方式相对比较麻烦,下面给出两种实现方式:

  (一)、借助先序遍历交换(后序遍历与此类似),可以用一个LinkedList的数据结构模拟栈来完成此操作。传入树的根节点root。

  1.如果root为空则结束交换,否则root 进栈。

  2.当栈不为空时进行如下操作:

    a.弹出栈顶节点,交换栈顶节点的左右孩子。

    b.如果栈顶元素的右孩子不为空,右孩子节点进栈;如果栈顶元素的左孩子不为空,左孩子节点进栈。

  算法实现:

 

 1     //运用先序遍历循环将该树转换为它的镜像,用LinkedList模拟栈来实现 DLR
 2     private void exchangeCirculatory(Node root){
 3         if(root==null){
 4             return;
 5         }
 6         LinkedList<Node> nodelist = new LinkedList<Node>();
 7         System.out.println();
 8         nodelist.add(root);           //根节点进栈
 9         while(nodelist.size()!=0){
10             root = nodelist.removeLast(); //获得栈顶元素
11             swap(root);
12             if(root.right!=null){     //如果栈顶元素的右孩子不为空,右孩子节点进栈
13                 nodelist.add(root.right);
14             }
15             if(root.left!=null){     //如果栈顶元素的左孩子不为空,左孩子节点进栈
16                 nodelist.add(root.left);
17             }
18         }
19     }

 

  (二)、借助层序遍历交换,可以用一个LinkedList的数据结构模拟队列来完成此操作。传入树的根节点root。

  1.如果root为空则结束交换,否则root 入队。

  2.当队列不为空时进行如下操作:

    a.队首元素出队,交换队首元素节点的左右孩子。

    b.如果队首元素的左孩子不为空,左孩子节点入队;如果队首元素的右孩子不为空,右孩子节点进栈。

算法实现:

 1     //层序遍历循环将该树转换为它的镜像,使用LinkedList数据结构来模拟队列
 2     private void levelOrder(Node root){
 3         if(root==null){
 4             System.out.println("\n二叉树为空!");
 5             return;
 6         }
 7         System.out.println("\n这是二叉排序树的层序遍历结果:");
 8         LinkedList<Node> queue = new LinkedList<Node>();
 9         queue.add(root);      //根节点先入队
10         while(queue.size()!=0){
11             Node node = queue.removeFirst();  //得到并删除队列的第一个节点
12             swap(node);
13             if(node.left!=null){   //该节点的左孩子入队
14                 queue.add(node.left);
15             }
16             if(node.right!=null){   //该节点的右孩子入队
17                 queue.add(node.right);
18             }
19         }
20         System.out.println();
21     }

 

java实现的完整源码:

  1 package com.interview;
  2 
  3 import java.util.LinkedList;
  4 
  5 import com.interview._16LeverOrder.Node;
  6 
  7 /**
  8  * 题目:输入一颗二元查找树,将该树转换为它的镜像,
  9  *     即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
 10  *     用递归和循环两种方法完成树的镜像转换。
 11  * @author wjh
 12  *
 13  */
 14 public class _15MirrorTree {
 15 
 16     /**
 17      * @param args
 18      */
 19     public static void main(String[] args) {
 20         _15MirrorTree builder= new _15MirrorTree();
 21         int[] a = {56,45,47,67,35,76,22,89,91,27,11,21,19,87};
 22         Node root = null;
 23         root = builder.buildTree(root, a); //1)创建二叉排序树
 24         System.out.println("这是原二叉树的中序遍历结果:");
 25         builder.inOrder(root);   //2)打印交换之前的二叉排序树的中序遍历结果
 26         
 27         builder.exchangeRecursive(root);  //3)递归交换二叉排序树的左右子树
 28         System.out.println("\n\n这是用递归将该树转换为它的镜像的中序遍历结果:");
 29         builder.inOrder(root);   //4)打印递归交换之后的二叉排序树的中序遍历结果
 30         
 31         builder.exchangeRecursive(root);  //5)将树转换回原二叉排序树
 32         builder.exchangeCirculatory(root);//6)循环交换二叉排序树的左右子树
 33         System.out.println("\n这是借助先序遍历循环将该树转换为它的镜像的中序遍历结果:");
 34         builder.inOrder(root);  //7)打印循环交换之后的二叉排序树的中序遍历结果
 35         
 36         builder.exchangeRecursive(root);  //8)将树转换回原二叉排序树
 37         builder.levelOrder(root);    //9)层序交换二叉排序树的左右子树
 38         System.out.println("\n这是借助层序循环将该树转换为它的镜像的中序遍历结果:");
 39         builder.inOrder(root);  //10)打印循环交换之后的二叉排序树的中序遍历结果
 40     }    
 41     
 42     //运用递归将该树转换为它的镜像
 43     private void exchangeRecursive(Node root){
 44         if(root!=null){    
 45             swap(root);         //交换根节点的左右子树
 46             exchangeRecursive(root.left);  //递归交换左子树
 47             exchangeRecursive(root.right); //递归交换右子树
 48         }
 49     }
 50     
 51     //运用先序遍历循环将该树转换为它的镜像,用LinkedList模拟栈来实现 DLR
 52     private void exchangeCirculatory(Node root){
 53         if(root==null){
 54             return;
 55         }
 56         LinkedList<Node> nodelist = new LinkedList<Node>();
 57         System.out.println();
 58         nodelist.add(root);           //根节点进栈
 59         while(nodelist.size()!=0){
 60             root = nodelist.removeLast(); //获得栈顶元素
 61             swap(root);
 62             if(root.right!=null){     //如果栈顶元素的右孩子不为空,右孩子节点进栈
 63                 nodelist.add(root.right);
 64             }
 65             if(root.left!=null){     //如果栈顶元素的左孩子不为空,左孩子节点进栈
 66                 nodelist.add(root.left);
 67             }
 68         }
 69     }
 70     
 71     //层序遍历循环将该树转换为它的镜像,使用LinkedList数据结构来模拟队列
 72     private void levelOrder(Node root){
 73         if(root==null){
 74             System.out.println("\n二叉树为空!");
 75             return;
 76         }
 77         LinkedList<Node> queue = new LinkedList<Node>();
 78         queue.add(root);      //根节点先入队
 79         while(queue.size()!=0){
 80             Node node = queue.removeFirst();  //得到并删除队列的第一个节点
 81             swap(node);
 82             if(node.left!=null){   //该节点的左孩子入队
 83                 queue.add(node.left);
 84             }
 85             if(node.right!=null){   //该节点的右孩子入队
 86                 queue.add(node.right);
 87             }
 88         }
 89         System.out.println();
 90     }
 91     
 92     //交换节点的左右子树
 93     private void swap(Node root){
 94         Node temp = root.left; 
 95         root.left = root.right;
 96         root.right = temp;
 97     }
 98     
 99     //二叉树的中序遍历
100     private void inOrder(Node root){
101         if(root==null){
102             return;            
103         }
104         else{
105             inOrder(root.left);
106             System.out.print(root.data+" ");
107             inOrder(root.right);
108         }
109     }
110     
111     //建二叉排序树
112     private Node buildTree(Node root, int[] data) {
113         for (int i = 0; i < data.length; i++) {
114         root=insert(root, data[i]);
115         }
116         return root;
117      }
118                 
119     //一次插入节点
120     private Node insert(Node node, int data) {
121         if (node == null) {
122             node = new Node(data,null,null);
123          }else{ 
124             if(data <= node.data) {
125                 node.left = insert(node.left, data);
126              } else {
127                 node.right = insert(node.right, data);
128              }
129          }
130          return node;
131     }
132     
133     //创建一个树节点类
134     class Node {
135         public int data;
136         public Node left;  //指向左孩子的指针    
137         public Node right;  //指向右孩子的指针    
138         public Node() {
139             super();
140         }
141         public Node(int data, Node left, Node right) {
142             super();
143             this.data = data;
144             this.left = left;
145             this.right = right;
146         }
147     }
148 
149 }
完整源码

运行结果:

这是原二叉树的中序遍历结果:
11 19 21 22 27 35 45 47 56 67 76 87 89 91

这是用递归将该树转换为它的镜像的中序遍历结果:
91 89 87 76 67 56 47 45 35 27 22 21 19 11

这是借助先序遍历循环将该树转换为它的镜像的中序遍历结果:
91 89 87 76 67 56 47 45 35 27 22 21 19 11

这是借助层序循环将该树转换为它的镜像的中序遍历结果:
91 89 87 76 67 56 47 45 35 27 22 21 19 11

 

posted @ 2015-01-29 17:17  武则天大人  阅读(782)  评论(0编辑  收藏  举报