Infinite Loop in Java, Stacks and LinkedLists - java

I'm working on the n-queens problem and am testing what I have so far to see if my logic is correct. My loop stops stops outputting and goes into an infinite loop after adjusting the 2nd queen piece so that there is no conflict.
I didn't think I'd get an infinite loop with my logic, which is basically:
Push (1,1)
Check for conflict
If conflict, adjust the top queen, if it can't be adjusted, pop off, adjust the new top
If no conflict and the size < 8, push (size+1, 1) -which would obviously be a conflict
Check for conflict
etc
public static boolean conflictCheck() {
QueenNode temp = head;
//walk through stack and check for conflicts
while(temp!=null) {
//if there is no next node, there is no conflict with it
if (temp.getNext() == null){
System.out.println("No next node");
if (queens.size() < 8 ) {
System.out.println("No problems");
return false;
}
}
else if (temp.getRow() ==temp.getNext().getRow() || temp.getColumn() == temp.getNext().getColumn() ||
diagonal(temp, temp.getNext())){
System.out.println("There's a conflict");
return true;
}
}
return false;
}
public static void playChess() {
System.out.println("Playing chess");
if (conflictCheck()) {
if (head.getColumn() == 8) {
queens.pop();
}
if (!queens.isEmpty()) {
System.out.println("Adjusting head");
head.setColumn(head.getColumn()+1);
System.out.println("Head is now " + head.getRow() + ", " + head.getColumn());
playChess();
}
}
else if (!conflictCheck() && queens.size() < 8) {
System.out.println("Stack isn't full yet");
queens.push(queens.size()+1,1);
playChess();
}
else {
success= true;
System.out.println("Success");
queens.viewPieces();
return;
}
}
public static void main(String[] args) {
queens.push(1, 1);
queens.viewPieces();
success = false;
playChess();
}
}
My output is:
The stack
1, 1
End of stack
Playing chess
No next node
No problems
No next node
No problems
Stack isn't full yet
Playing chess
There's a conflict
Adjusting head
Head is now 2, 2
Playing chess
problem
There's a conflict
Adjusting head
Head is now 2, 3
Playing chess

Was missing an extra else statement that determined when something wasn't a conflict

Related

Node problems with stack implementation of depth first search

If anyone could help me find out what I did wrong, it would be really appreciated. I have taken a few shots at this and have gotten closer with each version of my code. I started by having a linked list within the SearchPath class itself but now I moved it to the Node class. For some reason the code works and finds the end, but it does not properly remove some stuff from the stack. Feel free to give it a try. When the code finishes elements from the stack are supposed to be removed and it does but some extra coordinates end up in there. Not sure if it is because of the way I handled the processing of the already checked nodes or if it the recursion itself. This could also just be a horrible implementation of the problem that needs to be solved and maybe I need to think of another way to solve it, but I know the answer is right there. Possibly also take a look at how I included the linked list and stack as static variables within the node class. Should they have maybe been added elsewhere or could that have been causing some of the issues. Thanks a lot. Also the way it works is by inputting a grid of the same dimensions. Finish is indicated with F and start is indicated with S. The walls are X and the path is O to find the way throught path.
/* This program will implement a stack to try and traverse
a grid from a text file that contains a path. It will try
and find a path to the end and when it does it succeeds.
If it does not find the end that means that there was
not path that exists to it. Reads a file as input.
*/
import java.util.Stack;
import java.util.Scanner;
import java.io.File;
import java.io.FileReader;
import java.lang.Exception;
import java.util.LinkedList;
// This class will represent information about a part in the board and will be used by the
// algorithim to determine what to do next.
class Node {
private static Stack<Node> pathLocation = new Stack<>(); // Create a stack that will hold nodes for the algorithm
// to traverse the area.
private static LinkedList<int[]> checkedLocations = new LinkedList<int[]>();
private static int totalMoves = 0;
private int rowNumber, columnNumber;
private boolean checked;
public Node() { // Constructor for a default node.
}
// Gets the current node in the stack.
public Node getLocaiton() {
return pathLocation.peek();
}
// Removes a node from the stack.
public void removeLocation() {
pathLocation.pop();
}
// Adds a new node to the stack.
public void newLocation(Node nextPath) {
pathLocation.push(nextPath);
}
public Stack<Node> getStack() {
return pathLocation;
}
public int getRowLocation() {
return rowNumber;
}
public int getColumnLocation() {
return columnNumber;
}
public void setRowLocation(int inputRow) {
rowNumber = inputRow;
}
public void setColumnLocation(int inputColumn) {
columnNumber = inputColumn;
}
public void setChecked(boolean input) {
checked = input;
}
public boolean getChecked() {
return checked;
}
public int getTotalMoves() {
return totalMoves;
}
public void setTotalMoves(int input) {
totalMoves = input;
}
public boolean getChecked(int inputColumn, int inputRow) {
for (int[] i : checkedLocations) {
if (inputColumn == i[0] && inputRow == i[1]) {
return true;
}
}
return false;
}
public boolean addChecked(int inputColumn, int inputRow) {
this.setColumnLocation(inputColumn);
this.setRowLocation(inputRow);
for (int[] i : checkedLocations) {
if (this.getColumnLocation() == i[0] && this.getRowLocation() == i[1]) {
--totalMoves;
this.checked = true;
return this.checked;
}
}
int[] temp = { this.getColumnLocation(), this.getRowLocation() };
checkedLocations.push(temp);
this.checked = false;
++totalMoves;
return this.checked;
}
}
class Board {
private int size; // This will determine the size of the board which is obtained from the
// BoardFile class.
private char[][] boardArea; // The current location on the board. This current program supports double
// array. Could later be upgraded to support more dimensions.
private int boardColumn;
private int boardRow;
Board(BoardFile inputBoard) throws Exception { // This constructor could throw and exception.
Scanner boardRead = inputBoard.processedBoard(); // Obtained the scanner from the boardFile class.
String temp; // Strings that will be processed and saved by the scanner.
while (boardRead.hasNext()) { // Processes infromation from the board as long as there is information to read.
temp = boardRead.nextLine(); // Sets a temp string equal to what was next in the file.
int tempSize; // Remembers the size of the temp string.
size = temp.length(); // Sets the total size of game area.
boardColumn = size;
boardArea = new char[size][size];
int j = 0;
boolean startFound = false, endFound = false; // Makes sure there is a finish and a start.
while (temp.length() == size) {
for (int i = 0; i < temp.length(); ++i) { // This loop will construct the game board and
// and makes sure everything is correct.
if (temp.charAt(i) == 'X' || temp.charAt(i) == 'O' || temp.charAt(i) == 'F' || temp.charAt(i) == 'S') {
boardArea[i][j] = temp.charAt(i);
// The following if statements check to make sure there is only one instance of
// finish and start.
if (temp.charAt(i) == 'F' && !endFound) {
endFound = true;
}
else if (temp.charAt(i) == 'F' && endFound) {
throw new Exception("The finish was already found. Please check and try again.");
}
else if (temp.charAt(i) == 'S' && !startFound) {
startFound = true;
}
else if (temp.charAt(i) == 'S' && startFound) {
throw new Exception("The start was already found. Please check and try again.");
}
}
else {
// throws an exception in case one of the characters was not excpected.
throw new Exception("There was a incorrect character within the board. Please check and try again.");
}
}
if (boardRead.hasNext()) {
tempSize = temp.length(); // Assign the previous line size.
temp = boardRead.nextLine(); // Assign the next line.
if (tempSize != temp.length()) { // Check to make sure both lines are the same size.
throw new Exception("The size of the board is not correct. Please check and try again.");
}
}
else {
break;
}
++j; // Increment the row.
if (j > size - 1) { // Makes sure the area in the map is correct.
throw new Exception("The area in the map is not the same. Please check and try again.");
}
boardRow = j; // Sets the row number.
}
if (j != size - 1) {
throw new Exception("The area in the map is not the same. Please check and try again.");
}
if (!endFound) {
throw new Exception("The end was not found. Please check and try again.");
}
if (!startFound) {
throw new Exception("The start was not found. Please check and try again.");
}
}
}
public char[][] getBoardArea() { // Returns the array.
return boardArea;
}
public char getBoardLocation(int inputColumn, int inputRow) { // Gets a character a certain location
return boardArea[inputColumn][inputRow]; // within the array.
}
public int getBoardColumn() { // Gets the column total.
return boardColumn - 1;
}
public int getBoardRow() { // Gets the row total.
return boardRow;
}
}
// The class used to read a file.
class BoardFile {
private File file;
private FileReader createdBoard;
private Scanner readBoard;
BoardFile(String fileName) throws Exception { // Creates a file reader object.
file = new File(fileName);
if (!file.exists()) { // Makes sure the file is found.
throw new Exception("The file could not be found.");
}
createdBoard = new FileReader(file); // Creates the file reader.
readBoard = new Scanner(createdBoard); // Creates a new scanner object to read the board.
}
public Scanner processedBoard() { // Gets the scanner object from the read board.
return this.readBoard;
}
}
// This class is the actual searching and will be used to traverse the map.
public class PathSearch {
private Node node = new Node(); // Creates the node object to traverse the map area.
private Board board; // Creates the map.
private Integer[] saveLocation = new Integer[2]; // Create an array that saves a certain location.
PathSearch() throws Exception { // Accepts nothing but asks for a string that searchs for a file.
Scanner input = new Scanner(System.in);
String userFile;
System.out.println("Please enter the name of the file.");
userFile = input.nextLine();
input.close();
board = new Board(new BoardFile(userFile)); // This creates the board from a file that was input.
for (int i = 0; i < board.getBoardColumn(); ++i) { // Searches the board for the starting point.
for (int j = 0; j < board.getBoardRow(); ++j) {
if (board.getBoardLocation(i, j) == 'S') {
node.newLocation(new Node()); // Creates a new element in the stack.
saveLocation[0] = i; // Saves the column in which the node was found.
saveLocation[1] = j; // Saves the row in which the node was found.
System.out.println("Start found at " + (saveLocation[0]) + " " + (saveLocation[1]));
break; // Exits the loop since the information that was needed was processed.
}
}
}
if (saveLocation == null) {
throw new Exception("No starting point was found. Please check and try again.");
}
checkPath(saveLocation[0], saveLocation[1]);
}
// This method accepts two seperate inputs because it needs to remember if it
// checked the position it is currently at.
public Stack<Node> checkPath(int inputColumn, int inputRow) throws Exception {
node.addChecked(inputColumn, inputRow); // Get the current node and check if has been used already.
if (node.getChecked() && !node.getStack().empty()) { // Sees if it was checked and if the stack is not empty.
node.removeLocation(); // Removes the current node from the stack.
checkPath(node.getLocaiton()); // Uses the previous node to keep checking,
}
else {
Node tempNode = new Node(); // Creates a new temp node.
tempNode.setColumnLocation(inputColumn);
tempNode.setRowLocation(inputRow);
node.newLocation(tempNode); // Adds the temp node into the stack.
checkPath(node.getLocaiton()); // Starts checking at the new location.
}
return null; // Path was not found.
}
// This is a overloaded version of checkPath that accepts the current node
// and begins looking at the current node.
public Stack<Node> checkPath(Node node) throws Exception {
int inputColumn = node.getLocaiton().getColumnLocation();
int inputRow = node.getLocaiton().getRowLocation();
if (board.getBoardLocation(inputColumn, inputRow) == 'F') {
System.out.println("The end was found at " + node.getLocaiton().getColumnLocation()
+ " " + node.getLocaiton().getRowLocation());
System.out.println("Here is the path.");
while (!node.getStack().empty()) { // While the stack has information.
System.out.println(node.getLocaiton().getColumnLocation() + " " + node.getLocaiton().getRowLocation());
node.removeLocation(); // Remove the node to process the next.
}
System.out.println("The total moves were " + node.getTotalMoves());
return node.getStack();
}
// All statements to determine where to move next within the board.
if (inputColumn < board.getBoardColumn() && (board.getBoardLocation(inputColumn + 1, inputRow) == 'O'
|| board.getBoardLocation(inputColumn + 1, inputRow) == 'F')
&& !node.getChecked(inputColumn + 1, inputRow)) {
checkPath(inputColumn + 1, inputRow);
}
if (inputColumn > 0 && (board.getBoardLocation(inputColumn - 1, inputRow) == 'O'
|| board.getBoardLocation(inputColumn - 1, inputRow) == 'F')
&& !node.getChecked(inputColumn - 1, inputRow)) {
checkPath(inputColumn - 1, inputRow);
}
if (inputRow < board.getBoardRow() && (board.getBoardLocation(inputColumn, inputRow + 1) == 'O'
|| board.getBoardLocation(inputColumn, inputRow + 1) == 'F')
&& !node.getChecked(inputColumn, inputRow + 1)) {
checkPath(inputColumn, inputRow + 1);
}
if (inputRow > 0 && (board.getBoardLocation(inputColumn, inputRow - 1) == 'O'
|| board.getBoardLocation(inputColumn, inputRow - 1) == 'F')
&& !node.getChecked(inputColumn, inputRow - 1)) {
checkPath(inputColumn, inputRow - 1);
}
return null; // No path was found at that location.
}
}

Function Repeating Itself Even After Returning

I am making a Tic-Tac-Toe game with a computer player. However, whenever I call the computer's makeMove method, the computer continues to play without the user being able to do anything. Just to be sure that the function stopped, I made it return after each move, but it still plays the entire game without the user's input.
Here are the relevant parts:
Board Class:
public String addToBoard(char c, int square) {
if (!spaceFull(board, square)) {
int[] coords = getRowAndColumn(square);
//System.out.println("[" + coords[0] + "][" + coords[1] + "]");
board[coords[0]][coords[1]] = c;
return "VALID";
} else {
System.out.println("Space Is Occupied");
return "OCCUPIED";
}
}
public boolean spaceFull(char[][] b, int square) {
return (twoDimenToOneDimen(b).get(square - 1) == 'X' || twoDimenToOneDimen(b).get(square - 1) == 'O');
}
Computer Class
public void makeMove() {
int square;
//Checks For Any Winning Computer Moves
System.out.println("Here");
if ((square = nextMoveWinCheck(playerChar)) != 0) {
board.addToBoard(playerChar, square);
return;
//Checks For Any Opponent Winning Moves
} else if ((square = nextMoveWinCheck(opponentChar)) != 0) {
board.addToBoard(playerChar, square);
return;
} else {
//Checks If Computer Has First Move
if (boardEmpty()) {
board.addToBoard(playerChar, 9);
return;
} else {
//Moves Into Opposite Corner if Bottom Corner is Occupied By Itself
if (!board.spaceFull(board.board,1) && board.board[2][2] == playerChar) {
board.addToBoard(playerChar, 1);
return;
//Move Into Center If Second Move or Possible
} else if (!board.spaceFull(board.board,5)) {
board.addToBoard(playerChar, 5);
return;
} else if ((square = emptyCorner()) != 0) {
board.addToBoard(playerChar, square);
return;
} else {
board.addToBoard(playerChar, randomEmptySpot());
return;
}
}
}
}
If you want the full code, it's:
Computer
Board
Player
Tic-Tac-Toe Main Class
Your problem lies in your class Computer. On line 57, you assign board.board to tempBoard. However tempBoard still holds the reference to the object board.board, so whatever modifications you make there is reflected on the actual board. To resolve this, COPY the board values to tempboard:
http://www.java2s.com/Code/Java/Collections-Data-Structure/clonetwodimensionalarray.htm

Why is my break statement being ignored?

In my method under the if statement:
if (currentLocationX == 0 && currentLocationY == 4)
I have a break statement that should make the program exit out of the while loop and return true for 'answer' and for the method. Yet after some testing it seems that after returning true for 'answer', it goes back into the while loop giving the wrong results int the end. Why is my break statement not doing what it's supposed to? Thank you!
P.S. (this method calls on some other method that were not relevant to mention here)
public boolean solveMaze()
{
boolean answer = false;
int currentLocationX;
int currentLocationY;
//push starting location
pushX(2);
pushY(1);
while((isEmptyX() == false) && (isEmptyY() == false))
{
printMaze();
System.out.println();
currentLocationX = popX();
currentLocationY = popY();
//mark current location as visited
visited(currentLocationX, currentLocationY, maze);
System.out.println("Current Location: " + currentLocationX + ", " + currentLocationY);
if (currentLocationX == 0 && currentLocationY == 4)
{
answer = true;
break;
}
else
{
//push all unvisited OPEN neighbor locations into stack
if (checkEast(currentLocationX, currentLocationY) == 0)
{
pushX(eastX(currentLocationX));
pushY(eastY(currentLocationY));
}
else;
if (checkSouth(currentLocationX, currentLocationY)== 0)
{
pushX(southX(currentLocationX));
pushY(southY(currentLocationY));
}
else;
if (checkWest(currentLocationX, currentLocationY)== 0)
{
pushX(westX(currentLocationX));
pushY(westY(currentLocationY));
}
else;
if (checkNorth(currentLocationX, currentLocationY)== 0)
{
pushX (northX(currentLocationX));
pushY(northY(currentLocationY));
}
else;
}
}
return answer;
}
I wrote out the basic logic of your method as
public static boolean solveMaze() {
boolean answer = false;
int currentLocationX = 0;
int currentLocationY = 4;
while (true) {
if (currentLocationX == 0 && currentLocationY == 4) {
System.out.println("Hit the break");
break;
} else {
System.out.println("Missed the break");
}
}
return answer;
}
and if you execute it you get Hit the break. So your solveMaze() method is fine in terms of breaking out of the loop once it satisfies your if-statement. I would say that if you see your code subsequently going back into the while loop, it must be that solveMaze() was called a second time.

Java - Iterative deepening search with nodes

I'm in the process of designing a program that is meant to search through a two-dimensional array of numbers that represents a map for a path to a specified end point. I've been using nodes that have several parameters, most prominently adjacent north, south, east, and west nodes each representing a square within the map. The search method I'm currently trying to finish is with iterative deepening but every time I try running the program, I wind up with a stack overflow error. This is the iterative deepening class.
import java.util.*;
import java.io.*;
public class IDeepeningSearch {
private Node start;
private Node end;
private int[][] map;
private ArrayList<Node> solution;
//Build using file handler
public IDeepeningSearch(String file){
FileHandler handle = new FileHandler(file);
//Create map
map = handle.getMap();
//Start node coordinates and value
start = new Node();
start.setRow(handle.getSRow());
start.setCol(handle.getSCol());
start.setValue(map[start.getRow()][start.getCol()]);
//End node coordinates
end = new Node();
end.setRow(handle.getERow());
end.setCol(handle.getECol());
end.setValue(map[start.getRow()][start.getCol()]);
}
//Runs search
public void run(){
int i = 0;
solution = new ArrayList<Node>();
//Value of i indicates depth to be explored; will increment with each failure
while(solution.isEmpty()){
search(start, i);
i++;
}
if(!solution.isEmpty()){
System.out.println("It worked.");
}
System.out.println("If you're not seeing the other message then it failed.");
}
//Building tree
public void build(Node head){
setNLeaf(head);
setSLeaf(head);
setELeaf(head);
setWLeaf(head);
// if(head.getNorth() != null){
// build(head.getNorth());
// }
// if(head.getSouth() != null){
// build(head.getSouth());
// }
// if(head.getEast() != null){
// build(head.getEast());
// }
// if(head.getWest() != null){
// build(head.getWest());
// }
}
//Performs search
public void search(Node head, int depth){
if(head.getRow() == end.getRow() && head.getCol() == end.getCol()){
solution.add(head);
return;
}
else{
if(depth == 0){
return;
}
build(head);
if(head.getNorth() != null){
search(head.getNorth(), depth--);
}
if(head.getSouth() != null){
search(head.getSouth(), depth--);
}
if(head.getEast() != null){
search(head.getEast(), depth--);
}
if(head.getWest() != null){
search(head.getWest(), depth--);
}
}
}
//Sets north leaf
public void setNLeaf(Node node){
//Determines if parent is on edge of map and if desired space has 0 value
if(node.getRow() != 0 && map[node.getRow() - 1][node.getCol()] != 0){
Node n = new Node();
n.setRow(node.getRow() - 1);
n.setCol(node.getCol());
n.setValue(map[n.getRow()][n.getCol()]);
n.setParent(node);
node.setNorth(n);
}
}
//Sets south leaf
public void setSLeaf(Node node){
//Determines if parent is on edge of map and if desired space has 0 value
if(node.getRow() != (map.length - 1) && map[node.getRow() + 1][node.getCol()] != 0){
Node n = new Node();
n.setRow(node.getRow() + 1);
n.setCol(node.getCol());
n.setValue(map[n.getRow()][n.getCol()]);
n.setParent(node);
node.setSouth(n);
}
}
//Sets east leaf
public void setELeaf(Node node){
//Determines if parent is on edge of map and if desired space has 0 value
if(node.getRow() != (map[0].length - 1) && map[node.getRow()][node.getCol() + 1] != 0){
Node n = new Node();
n.setRow(node.getRow());
n.setCol(node.getCol() + 1);
n.setValue(map[n.getRow()][n.getCol()]);
n.setParent(node);
node.setEast(n);
}
}
//Sets west leaf
public void setWLeaf(Node node){
//Determines if parent is on edge of map and if desired space has 0 value
if(node.getCol() != 0 && map[node.getRow()][node.getCol() - 1] != 0){
Node n = new Node();
n.setRow(node.getRow());
n.setCol(node.getCol() - 1);
n.setValue(map[n.getRow()][n.getCol()]);
n.setParent(node);
node.setWest(n);
}
}
}
I thought I was doing this correctly but the errors I've been getting have been pretty constant. This is what I wind up with.
Exception in thread "main" java.lang.StackOverflowError
at Node.setSouth(Node.java:88)
at IDeepeningSearch.setSLeaf(IDeepeningSearch.java:113)
at IDeepeningSearch.build(IDeepeningSearch.java:48)
at IDeepeningSearch.search(IDeepeningSearch.java:75)
at IDeepeningSearch.search(IDeepeningSearch.java:77)
at IDeepeningSearch.search(IDeepeningSearch.java:80)
at IDeepeningSearch.search(IDeepeningSearch.java:77)
The second-to-last and last lines repeat. I've tried building a full tree as well but that either gives me another stack overflow error or a null pointer exception. I'm not really sure what the issue is here but if I can fix this, I'm sure I can finish my breadth-first search method as well.
depth-- evaluates to the original value of depth. This means that the unmodified version of depth is being passed to the recursive call to search(), so your code is never approaching the base case. Try depth-1 instead. Or, if you need the value of the local variable depth to change, --depth.
For example, this will continually print 10 until it reaches stack overflow
public void foo(int x) {
if (x == 0) {
return;
}
System.out.println(x);
foo(x--);
}
foo(10);
The StackOverflowError is because of the flawed recursive calls of search(node, depth--) as Chris Rise has mentioned in his answer. Try --depth to fix this.
There is also poor memory management in this code, which is wasting heap memory that could either slow the program due to several calls to GC (Garbage-Collector) or lead to an OutOfMemeoryError! This problem is visible in the setXLeaf(Node n) methods (e.g. setNLeaf(Node north) etc.) where every time you are creating a new Node, while this can be done only when it's necessary with a simple check:
if (node.getSouth() == null) {
Node n = new Node();
n.setParent(node);
node.setSouth(n);
}
node.getSouth().setRow(node.getRow() + 1);
node.getSouth().setCol(node.getCol());
node.getSouth().setValue(map[node.getRow() + 1][node.getCol()]);
This way you will avoid creating new objects that are unnecessary. This should be fixed in all the setXLeaf(...) methods.

Decoding a message with Huffman tree

When I send a string of bits to be decoded, it seems to require one additional bit to decode properly. I've printed out the tree in pre-order, and I've drawn the tree on paper to make sure I wasn't missing something. The pre-order and my drawn tree match, but the bits required to produce the correct letter is off.
public void decode(String code){
String result = "";
TreeNode current = root;
current.preOrder();
for(int i = 0;i < code.length();i++){
//left--0
if(Character.getNumericValue(code.charAt(i))==0){
if(current.getLeft() == null){
result += current.getWeight().getLetter();
current = root;
i--;
}else
current=current.getLeft();
}
//right--1
else if(Character.getNumericValue(code.charAt(i))==1){
if(current.getRight() == null){
result += current.getWeight().getLetter();
current = root;
i--;
}else
current=current.getRight();
}
}
System.out.println(result);
}
My tree is building correctly every time which makes me believe the error is in the decoding method. However, I can't seem to figure out why it needs additional bits.
Without seeing how your nodes are laid out I can only guess. When traversing left/right you probably need to check if you've landed on a leaf node and emit its character if so.
if (current.getLeft() == null) {
...
}
else {
current = current.getLeft();
if (current.isLeaf()) {
result += current.getWeight().getLetter();
current = root;
}
}
The same goes for the right side.
Don't Repeat Yourself
To avoid duplicating the two lines that append the character and reset the current node to the root four times, you could instead set a flag and check it at the end of the for block.
boolean append = false;
if (Character.getNumericValue(code.charAt(i)) == 0) {
if (current.getLeft() == null) {
append = true;
i--;
}
else {
current = current.getLeft();
if (current.isLeaf()) {
append = true;
}
}
}
// same for right side ...
if (append) {
result += current.getWeight().getLetter();
current = root;
}
Other Tips
Switch from two if checks for 0 or 1 to a switch with a default that throws an IllegalArgumentException.
Switch the for loop to a while to avoid pre-decrementing i just to have it incremented again and avoid stopping the loop.
Start with append set to true since four out of six cases append.

Categories