[英]Given a Perfect Binary Tree, reverse the alternate level nodes of the binary tree
I have to solve the following problem: Given a perfect binary tree, that stores characters on its nodes, reverse the nodes on the odd levels. 我必须解决以下问题:给定一个完美的二叉树,该树将字符存储在其节点上,将这些节点反转为奇数级。 The problem and the solution are taken from here: http://www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/ . 问题和解决方案从此处获取: http : //www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/ 。
I am trying to implement the tricky solution. 我正在尝试实施棘手的解决方案。 This is my code: 这是我的代码:
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class ReverseLevel {
public static class Node{
char id;
Node left;
Node right;
public Node(char id){
this.id = id;
left = null;
right = null;
}
}
static Node root;
static Queue<Node> q;
static int index;
static List<Character> res = new ArrayList<Character>();
public static void main(String[] args) {
createBT();
printLevelbyLevel(root);
reverseLevels(root, 0);
int n = res.size();
System.out.println();
for (int i = 0; i < n; i++) {
System.out.print(res.get(i) + " ");
}
System.out.println();
setLevels(root, 0, n-1);
printLevelbyLevel(root);
}
private static void printLevelbyLevel(Node root2) {
q = new LinkedList<Node>();
q.add(root);
Queue<Node> nextLevel = new LinkedList<Node>();
while(!q.isEmpty()){
Node n = q.remove();
printNode(n);
if(hasLeftChild(n)){
nextLevel.add(n.left);
}
if(hasRightChild(n)){
nextLevel.add(n.right);
}
if(q.isEmpty()){
System.out.println();
while(!nextLevel.isEmpty()){
q.add(nextLevel.poll());
}
}
}
}
private static void reverseLevels(Node root, int level){
if(root == null){
return;
}
reverseLevels(root.left, level+1);
if(level%2 == 1){
res.add(root.id);
}
reverseLevels(root.right, level+1);
}
private static void setLevels(Node root, int level, int index){
if(root == null){
return;
}
setLevels(root.left, level+1, index);
if(level%2 == 1){
root.id = res.get(index);
index--;
}
setLevels(root.right, level+1, index);
}
private static boolean hasRightChild(Node n) {
if(n.right != null)
return true;
return false;
}
private static boolean hasLeftChild(Node n) {
if(n.left != null)
return true;
return false;
}
private static void printNode(Node n) {
System.out.print(n.id + " ");
}
private static void createBT() {
Node n1 = new Node('a');
Node n2 = new Node('b');
Node n3 = new Node('c');
Node n4 = new Node('d');
Node n5 = new Node('e');
Node n6 = new Node('f');
Node n7 = new Node('g');
Node n8 = new Node('h');
Node n9 = new Node('i');
Node n10 = new Node('g');
Node n11 = new Node('k');
Node n12 = new Node('l');
Node n13 = new Node('m');
Node n14 = new Node('n');
Node n15 = new Node('o');
root = n1;
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n4.left = n8;
n4.right = n9;
n5.left = n10;
n5.right = n11;
n3.left = n6;
n3.right = n7;
n6.left = n12;
n6.right = n13;
n7.left = n14;
n7.right = n15;
}
} }
The idea is to traverse the tree in-order
fashion, store the nodes from odd levels in an ArrayList
res
and then again traverse the tree in in-order
fashion and for each node which is in odd level, I replace its id by the corresponding value in res
. 这个想法是按in-order
遍历树,将奇数级的节点存储在ArrayList
res
,然后再次in-order
遍历树,对于奇数级的每个节点,我将其id替换为res
价值。 While the second in-order traversal, I keep field index, which tells me from which index of res
I should take my data. 而第二中序遍历,我一直在外地指标,它告诉我从哪个指标res
我应该把我的数据。
Whenever I replace the data in the corresponding node with that from res
, I decrement index
. 每当我用res
的数据替换相应节点中的数据时,我都会减少index
。 However since it is a recursion, if I go in upper levels of the recursion, the value of index
gets the same as before, and I don't change the data of the nodes correctly. 但是,由于这是递归,所以如果我进入递归的较高级别,则index
的值将与以前相同,并且我无法正确更改节点的数据。 Can someone suggest me how can I avoid this? 有人可以建议我如何避免这种情况吗? I have included methods for printing the tree level by level, so it is visible that the method doesn't work correctly. 我已经包括了逐级打印树的方法,因此可见该方法无法正常工作。
I'll admit i havent read the your program, what caught me was that you mentioned odd levels
and you are doing inorder
traversal.Thats quiet odd for me! 我承认我还没有阅读您的程序,让我inorder
是您提到了odd levels
并且您正在执行inorder
遍历。
If i would code this, here would be my approach : 如果我要编写代码,这就是我的方法:
if i have to work on level 's in BST, i'll go with level-order-traversal
( BFS simply ) and keep a track of odd levels. 如果非要平 “的BST的工作,我会去与level-order-traversal
(BFS简单 ),并保持奇数水平的轨道。
Then,on every odd level, on deQueue
ing a value of a node, i'll swap it with the current node value. 然后,在每个奇数级上,在对一个节点的值进行deQueue
,我将其与当前节点值交换。 ( that's it !!) ( 就是这样 !)
This is more space efficient ( no stack space needed ) and is achieved in O(n) time 这样更节省空间( 不需要堆栈空间 ),并在O(n)时间内实现
Example : 范例:
10 //Level 0
/ \
5 20 //Level 1
/ \ / \
1 3 12 25 //Level 2
When enQueue
d for Level-1, You will have 5
in deQueue
and 20
at the front
of Queue
. 当enQueue
d为1级,你将有5
在deQueue
和20
在front
的Queue
。
Now, just check if the level is odd.If yes, then swap the deQueue
ed value with the value of node in the front! 现在,只需检查级别是否为奇数,如果是,则将deQueue
ed值与前面的node值交换!
5<=>20 in this case
You should use a java.util.Stack to push and pop the nodes. 您应该使用java.util.Stack推送和弹出节点。 Here is a modified version of your code: 这是您的代码的修改后的版本:
public class ReverseLevel {
public static class Node {
char id;
Node left;
Node right;
public Node(char id) {
this.id = id;
left = null;
right = null;
}
}
static Node root;
static Queue<Node> q;
static int index;
static Stack<Character> stack = new Stack<Character>();
public static void main(String[] args) {
createBT();
printLevelbyLevel(root);
reverseLevels(root, 0);
setLevels(root, 0);
printLevelbyLevel(root);
}
private static void printLevelbyLevel(Node root2) {
q = new LinkedList<Node>();
q.add(root);
Queue<Node> nextLevel = new LinkedList<Node>();
while (!q.isEmpty()) {
Node n = q.remove();
printNode(n);
if (hasLeftChild(n)) {
nextLevel.add(n.left);
}
if (hasRightChild(n)) {
nextLevel.add(n.right);
}
if (q.isEmpty()) {
System.out.println();
while (!nextLevel.isEmpty()) {
q.add(nextLevel.poll());
}
}
}
}
private static void reverseLevels(Node root, int level) {
if (root == null) {
return;
}
reverseLevels(root.left, level + 1);
if (level % 2 == 1) {
stack.push(root.id);
}
reverseLevels(root.right, level + 1);
}
private static void setLevels(Node root, int level) {
if (root == null) {
return;
}
setLevels(root.left, level + 1);
if (level % 2 == 1) {
root.id = stack.pop();
}
setLevels(root.right, level + 1);
}
private static boolean hasRightChild(Node n) {
if (n.right != null)
return true;
return false;
}
private static boolean hasLeftChild(Node n) {
if (n.left != null)
return true;
return false;
}
private static void printNode(Node n) {
System.out.print(n.id + " ");
}
private static void createBT() {
Node n1 = new Node('a');
Node n2 = new Node('b');
Node n3 = new Node('c');
Node n4 = new Node('d');
Node n5 = new Node('e');
Node n6 = new Node('f');
Node n7 = new Node('g');
Node n8 = new Node('h');
Node n9 = new Node('i');
Node n10 = new Node('g');
Node n11 = new Node('k');
Node n12 = new Node('l');
Node n13 = new Node('m');
Node n14 = new Node('n');
Node n15 = new Node('o');
root = n1;
n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n4.left = n8;
n4.right = n9;
n5.left = n10;
n5.right = n11;
n3.left = n6;
n3.right = n7;
n6.left = n12;
n6.right = n13;
n7.left = n14;
n7.right = n15;
}
}
Use Collections.reverse(res) after calling reverseLevels() . 在调用reverseLevels()之后使用Collections.reverse(res ) 。 This will reverse your ArrayList. 这将反转您的ArrayList。
In the function setLevels() instead of below code 在函数setLevels()中,而不是下面的代码
if(level%2 == 1)
{
root.id = res.get(index);
index--;
}
use below snippet. 在以下代码段中使用。 Then there will be no need to use index as the element you want is the first element and you remove it. 这样就不需要使用index了,因为您想要的元素是第一个元素,然后将其删除。
if(level%2 == 1)
{
root.id = res.get(0);
res.remove(0);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.