声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明。谢谢。
题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换。
题目分析:
注:二叉排序树的中序遍历结果是升序排序的,因此将该树转换为它的镜像之后,该树的中序遍历结果应是降序排序的。
一、递归实现:
这种方式相对比较好实现,传入树的根节点,当节点不为空时,交换根节点的左右孩子,再递归交换左右子树的左右孩子。
算法实现:
1 private voidexchangeRecursive(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 private voidexchangeCirculatory(Node root){2 if(root==null){3 return;4 }5 LinkedList nodelist = new LinkedList();6 System.out.println();7 nodelist.add(root); //根节点进栈
8 while(nodelist.size()!=0){9 root = nodelist.getLast(); //获得栈顶元素
10 swap(root); //交换栈顶元素的左右孩子
11 nodelist.removeLast();12 if(root.left!=null){ //如果栈顶元素的左孩子不为空,左孩子节点进栈
13 nodelist.add(root.left);14 }15 if(root.right!=null){ //如果栈顶元素的右孩子不为空,右孩子节点进栈
16 nodelist.add(root.right);17 }18 }19 }
java实现的完整源码:
1 packagecom.interview;2
3 importjava.util.LinkedList;4
5 /**
6 * 题目:输入一颗二元查找树,将该树转换为它的镜像,7 * 即在转换后的二元查找树中,左子树的结点都大于右子树的结点。8 * 用递归和循环两种方法完成树的镜像转换。9 *@authorwjh10 *11 */
12 public class_15MirrorTree {13
14 /**
15 *@paramargs16 */
17 public static voidmain(String[] args) {18 _15MirrorTree builder= new_15MirrorTree();19 int[] a = {56,45,47,67,35,76,22,89,91,27,11,21,19,87};20 Node root = null;21 root = builder.buildTree(root, a); //1)创建二叉排序树
22 System.out.println("这是原二叉树的中序遍历结果:");23 builder.inOrder(root); //2)打印交换之前的二叉排序树的中序遍历结果
24
25 builder.exchangeRecursive(root); //3)递归交换二叉排序树的左右子树
26 System.out.println("\n\n这是用递归将该树转换为它的镜像的中序遍历结果:");27 builder.inOrder(root); //3)打印递归交换之后的二叉排序树的中序遍历结果
28
29 builder.exchangeRecursive(root); //4)将树转换回原二叉排序树
30 builder.exchangeCirculatory(root);//5)循环交换二叉排序树的左右子树
31 System.out.println("\n这是用循环将该树转换为它的镜像的中序遍历结果:");32 builder.inOrder(root); //5)打印循环交换之后的二叉排序树的中序遍历结果
33 }34
35 //运用递归将该树转换为它的镜像
36 private voidexchangeRecursive(Node root){37 if(root!=null){38 swap(root); //交换根节点的左右子树
39 exchangeRecursive(root.left); //递归交换左子树
40 exchangeRecursive(root.right); //递归交换右子树
41 }42 }43
44 //运用循环将该树转换为它的镜像,用LinkedList模拟栈来实现
45 private voidexchangeCirculatory(Node root){46 if(root==null){47 return;48 }49 LinkedList nodelist = new LinkedList();50 System.out.println();51 nodelist.add(root); //根节点进栈
52 while(nodelist.size()!=0){53 root = nodelist.getLast(); //获得栈顶元素
54 swap(root); //交换栈顶元素的左右孩子
55 nodelist.removeLast();56 if(root.left!=null){ //如果栈顶元素的左孩子不为空,左孩子节点进栈
57 nodelist.add(root.left);58 }59 if(root.right!=null){ //如果栈顶元素的右孩子不为空,右孩子节点进栈
60 nodelist.add(root.right);61 }62 }63 }64
65 //交换节点的左右子树
66 private voidswap(Node root){67 Node temp =root.left;68 root.left =root.right;69 root.right =temp;70 }71
72 //二叉树的中序遍历
73 private voidinOrder(Node root){74 if(root==null){75 return;76 }77 else{78 inOrder(root.left);79 System.out.print(root.data+" ");80 inOrder(root.right);81 }82 }83
84 //建二叉排序树
85 private Node buildTree(Node root, int[] data) {86 for (int i = 0; i < data.length; i++) {87 root=insert(root, data[i]);88 }89 returnroot;90 }91
92 //一次插入节点
93 private Node insert(Node node, intdata) {94 if (node == null) {95 node = new Node(data,null,null);96 }else{97 if(data <=node.data) {98 node.left =insert(node.left, data);99 } else{100 node.right =insert(node.right, data);101 }102 }103 returnnode;104 }105
106 //创建一个树节点类
107 classNode {108 public intdata;109 public Node left; //指向左孩子的指针
110 public Node right; //指向右孩子的指针
111 publicNode() {112 super();113 }114 public Node(intdata, Node left, Node right) {115 super();116 this.data =data;117 this.left =left;118 this.right =right;119 }120 }121
122 }
完整源码
运行结果:
这是原二叉树的中序遍历结果:
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
原文:http://www.cnblogs.com/wuzetiandaren/p/4260432.html