JAVA deleting multiple consecutive elements from a circular linked list - java

I am pretty far along on my project dealing with singly circular linked lists and am still having trouble with one point. My trouble stems from not being able to/knowing how to call the node before the node containing the first of the four consecutive colors and referring it to the beginning.
Prompt for Marbles game:
Place random marbles in a circle and if four of the same color appear, remove them and add four times the color score to the total score.
I would really appreciate if someone could help me figure how to resolve this problem..
Here's the code I'm working on:
public void deleteQuadruples()
{
//if the list has 4 nodes, delete all and make a new head
if (size == 4 && (start.getaMarble().getNumber() == start.getNextLink().getaMarble().getNumber()
&& start.getNextLink().getaMarble().getNumber() == start.getNextLink().getNextLink().getaMarble().getNumber()
&& start.getNextLink().getNextLink().getaMarble().getNumber() == start.getNextLink().getNextLink().getNextLink().getaMarble().getNumber()))
{
sum = 4*start.getaMarble().getNumber();
start = new Link(null, null);
addFirstMarble();
}
//else go thru the list and find whether or not there are four consecutive marbles of the same color/number and if so take them out
else
{
Link tmp = start;
if (tmp == null)
{
return;
}
do
{
/*int colorNumber = tmp.getaMarble().getNumber();
int counter = 1;
tmp = tmp.getNextLink();
if(colorNumber == tmp.getaMarble().getNumber())
{
counter++;
}
if(counter == 4)
{
score += 4*tmp.getaMarble().getNumber();
counter = 1;
//delete the 4 consecutive elements
}
if(tmp.getNextLink() == start && counter == 3 && start.getaMarble().getColor() == tmp.getaMarble().getColor())
{
score += 4*tmp.getaMarble().getNumber();
start = start.getNextLink();
//delete the 4 consecutive elements
}*/
for(Link cursor = start; cursor != end; cursor = cursor.getNextLink)
{
Link temp;
counter = 1;
if(cursor.getaMarble().getNumber() == cursor.getNextLink().getaMarble().getNumber())
{
counter++;
}
if(cursor.getaMarble().getNextLink().getNumber() != cursor.getNextLink().getNextLink().getaMarble().getNumber())
{
counter = 1;
}
if (counter == 4)
{
//deletes the four consecutive nodes with same color
//something.getNextLink() = start;
score += 4* cursor.getaMarble.getNumber();
}
}
}
while (tmp != start);
}
}

I made some changes to your code (it may not compile but will give an idea)
public void deleteQuadruples()
{
if (start == null || size == 3)
return;
//if the list has 4 nodes, delete all and make a new head
if (size == 4 && (start.getaMarble().getNumber() == start.getNextLink().getaMarble().getNumber()
&& start.getNextLink().getaMarble().getNumber() == start.getNextLink().getNextLink().getaMarble().getNumber()
&& start.getNextLink().getNextLink().getaMarble().getNumber() == start.getNextLink().getNextLink().getNextLink().getaMarble().getNumber()))
{
sum = 4*start.getaMarble().getNumber();
start = new Link(null, null);
addFirstMarble();
}
//else go thru the list and find whether or not there are four consecutive marbles of the same color/number and if so take them out
else
{
Node end = start;
while (end.getNextLink().getaMarble().getNumber() != start.getNextLink().getaMarble().getNumber())
{ end = end.getNextLink(); }
// no data
if(end.getNextLink().getaMarble().getNumber() == start.getaMarble().getNumber())
return;
// we have data
else {
sum = 4*start.getaMarble().getNumber();
// loop four times
// set the end.getNextLink() with start.getNextLink()
}
}
}

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.
}
}

My LinkedList doesn't show up corectly after sorting

I have created in my program my own LinkedList (not from java.util) of cards.
Each card is an object made of 2 ints - the first one is a value ("wartosc" in my code) of a card (from 1 to 13), second is a colour ("kolor" in my code) for a card (from 0 to 3).
The list is randomly generated and the list is created when a value is 0.
Now I have to modify "add" method ("dodaj" in my code) to make it add cards in correct place in the list. Not sorting method adds cards and the rest works fine (all cards are shown) but when I use method that is supposed to add cards in order and when I then try to print list of cards it shows only like from 2 to 5 of them - all sorted except for the last one. But when I print the size of list ot shows numbers like 20 or even 40, even though I print only 4. So i would like to know what is wrong. Here is the code:
public class Lista {
private Element pocz; //start
public int rozmiar;
public Lista() {
boolean zrobione = false;
while (zrobione != true) {
Karta karta = new Karta();
if (karta.getWartosc() == 0) {
zrobione = true;
} else {
this.dodaj(karta);
}
}
}
public void dodaj(Karta k){
if(pocz == null)
pocz = new Element(k);
Element pom = new Element(k);
Element obecny = pocz;
boolean zrobione = false;
if(obecny != null && !zrobione){
while(obecny.getNext() !=null && (obecny.getNext().getKarta().wartosc > obecny.getKarta().wartosc || (obecny.getNext().getKarta().wartosc == obecny.getKarta().wartosc && obecny.getNext().getKarta().kolor > obecny.getKarta().kolor))){
obecny = obecny.getNext();
}
obecny.setNext(pom);
zrobione = true;
}
rozmiar++;
}
// public void dodaj(Karta k) {
// if (pocz == null) {
// pocz = new Element(k);
// }
//
// Element pom = new Element(k);
// Element obecny = pocz;
// if (obecny != null) {
// while (obecny.getNext() != null) {
// obecny = obecny.getNext();
// }
// obecny.setNext(pom);
// }
// rozmiar++;
// }
public int getRozmiar(){
return rozmiar;
}
public void drukujOKolorze(int kolor){
if(kolor<0 || kolor>4)
System.out.println("Bledny kolor");
else{
Element obecny = null;
if(pocz != null){
obecny = pocz.getNext();
while(obecny.getNext() != null){
if(obecny.getKarta().kolor == kolor)
System.out.println(obecny.getKarta().toString());
obecny = obecny.getNext();
}
}
}
}
public void drukujOWartosci(int wartosc){
if(wartosc<0 || wartosc>13)
System.out.println("Bledna wartosc");
else{
Element obecny = null;
if(pocz != null){
obecny = pocz.getNext();
while(obecny.getNext() != null){
if(obecny.getKarta().wartosc == wartosc)
System.out.println(obecny.getKarta().toString());
obecny = obecny.getNext();
}
}
}
}
public void wyswietl(){
if(pocz != null){
Element obecny = pocz.getNext();
while(obecny != null) {
System.out.println(obecny.getKarta().toString());
obecny = obecny.getNext();
}
}
}
}
Sorry for not using English names - I will put below a short dictionary :)
Lista() is constructor of List it checks if generated value is 0, then uses "dodaj" method
"dodaj" method is "add" the first one is supposed to sort cards
second "dodaj" that i put i comment for now was the 1st one that just adds new
cards. They aren't sorted but next methods work as intended when I use this one.
getRozmiar() returns size of List, "rozmiar" means "size"
"drukujOKolorze" and "drukujOWartosci" are supposed to print respectively:
cards of given colour and cards of given value - they work fine.
and finally "wyswietl" which is "print". When i use the second "dodaj" it prints all the cards that are in list. When I use the first "dodaj" it shows only like 2 to 5 cards and the last one is never sorted while "getSize()" shows that there is more cards in the list.
I hope You guys will help me. I have no idea what goes wrong here and no, I can't use compareTo. My task is to write method that will put cards in order.
When you find the place that you want to put your card, you are setting it as the next item in the linked list, but not re-attaching the rest of the list after the new entry, effectively removing all cards after the insertion point.
Imagine it as an actual chain of metal links.
You open one of the links in the middle, breaking the chain into two pieces, then add the new link to one side. However, you are not attaching the other half of the chain to the new link, so it is lost.
Try this:
public void dodaj(Karta k){
if(pocz == null)
pocz = new Element(k);
Element pom = new Element(k);
Element obecny = pocz;
boolean zrobione = false;
if(obecny != null && !zrobione){
while(obecny.getNext() !=null && (obecny.getNext().getKarta().wartosc > pom.getKarta().wartosc || (obecny.getNext().getKarta().wartosc == pom.getKarta().wartosc && obecny.getNext().getKarta().kolor > pom.getKarta().kolor))){ // Modified line
obecny = obecny.getNext();
}
pom.setNext(obecny.getNext()); // Added line
obecny.setNext(pom);
zrobione = true;
}
rozmiar++;
}

Getting the most frequent letter the words in a list of String nodes starts using recursion

I have the class:
public class WordNode {
private String _word;
private WordNode _next;
....
}
and the following list:
public class TextList {
private WordNode _head;
public char mostFrequentStartingLetter(....){}
}
In the TextList class I should use a recursive method (mostFrequentStartingLetter) which returns the most frequent letter the words in the list starts with...
I have no idea from where to start even.....
Please help...
Thanks,
Alona
Just so you know i am not cheating:
public class TextList {
private WordNode _head;
public TextList(String text) {
String word = "";
WordNode tmp;
// After the split that in the array we are going over all the array
for (int i = 0; i < text.length(); i++) {
for (int j = 0; j < text.length(); j++) {
if (text.charAt(j) == ' ') {
word = text.substring(0, j);
text = text.substring(j + 1);
i = 0;
break;
} else if (j == text.length() - 1) {
word = text.substring(0, j + 1);
text = text.substring(j + 1);
break;
}
}
if (_head == null) {
tmp = new WordNode(word, null);
_head = tmp;
}
// if the word starts with a smalles letter then the head, make it
// the head
else if (_head.getWord().compareTo(word) > 0) {
tmp = new WordNode(word, _head);
_head = tmp;
} else {
WordNode current;
current = _head;
// go over all the nodes in the list and push the current word
// to the list in the right order
while (current.getNext() != null) {
if (current.getWord().compareTo(word) < 1
&& current.getNext().getWord().compareTo(word) > 0) {
tmp = new WordNode(word, current.getNext());
current.setNext(tmp);
break;
}
current = current.getNext();
}
// If the current was the tail, check that the word is bigger
// and then make it the tail.
if (current.getNext() == null
&& current.getWord().compareTo(word) < 1) {
tmp = new WordNode(word, null);
current.setNext(tmp);
}
}
}
}
public String mostFrequentWord() {
String frequentWord = _head.getWord();
WordNode current = _head;
int count = 0;
int max = 0;
while (current.getNext() != null) {
if (current.getWord().compareTo(current.getNext().getWord()) == 0) {
count++;
}
if (count > max) {
max = count; frequentWord = current.getWord();
}
current = current.getNext();
}
return frequentWord;
}
public String toString() {
String s = "";
WordNode current = _head;
int count = 1;
while (current != null) {
while (current.getNext() != null && current.getWord().equals(current.getNext().getWord())) {
count++;
current = current.getNext();
}
s += current.getWord() + "\t" + count + "\n";
count = 1;
current = current.getNext();
}
return s;
}
public char mostFrequentStartingLetter(....){}
}
Since this is homework, I'll only give you some hints.
There are two things you need to do here.
Iterate over your linked list recursively.
Keep track of starting letters.
When you have a recursive function, you need a stopping condition. Think about the stopping condition for your linked list. How do you know when you have reached the end of your linked list? What would the value of _next be?
Your method would end up looking something like this:
///The pieces in the angle brackets are for you to figure out.
public void determineStartingLetter(WordNode currentNode) {
if(!<stopping condition>) {
determineStartingLetter(<next node after currentNode>);
}
}
Now this only traverses the linked list. You also need to keep track of the starting characters you've seen so far. Think about the structure you could use to do that. You want to map the character to the number of times you've seen it. What data structure would do that for you?
Now where could you maintain such a structure? The easiest solution (but not the most maintainable or elegant) would be a private member of the TextList class. But there is a better way. What if you could simply pass this data structure into the recursive method, and then pass into every recursive call?
So then your method would look like this:
//As before, the things in angle brackets are for you to figure out.
public <data structure> determineStartingLetter(WordNode currentNode, <data structure>) {
if(!stopping condition>) {
<look at starting letter for currentNode>
<increment the count for this letter in the data structure>
return determineStartingLetter(<next node after currentNode>, <data structure>);
}
return <data structure>
}
This should give you enough of a hint to figure out how to do it. In the second part I've actually given you some more hints than I should have :).

Java array - Adjacent cards

I'm trying to create a program that arranges 6 cards on a grid in a specific way so that no card is adjacent to other cards of the same type (the types being king, queen and jack). The grid is 4x4 but I can only place cards inside the following pattern:
[ ][ ][x][ ]
[x][x][x][ ]
[ ][x][x][x]
[ ][ ][x][ ]
Now, my main problem is when my method tries to check the adjacent cells for card types. When it starts at 0,0 it tries to check [row-1][column] which obviously won't work since that translates to -1,0. The problem is, I have no idea how implement this properly.
I apologise if this question has been asked before, as I wasn't sure what to search for exactly (or how to properly name this problem).
private boolean bordersCard(int row, int column, char cardChar)
{
Candidate center = board[row][column];
Candidate top;
Candidate bottom;
Candidate left;
Candidate right;
if (board[row-1][column] != null){
top = board[row+1][column];
}
else
{
top = new Candidate('?', 0);
}
if (board[row+1][column] != null){
bottom = board[row+1][column];
}
else
{
bottom = new Candidate('?', 0);
}
if (board[row][column-1] != null){
left = board[row][column-1];
}
else
{
left = new Candidate('?', 0);
}
if (board[row][column+1] != null){
right = board[row][column+1];
}
else
{
right = new Candidate('?', 0);
}
if ((center.getCardChar() == top.getCardChar()) || (center.getCardChar() == bottom.getCardChar()) ||
(center.getCardChar() == left.getCardChar()) || (center.getCardChar() == right.getCardChar())){
return false;
}
return true;
}
You have to add if fences to prevent the invalid checks:
if (row > 0 && board[row-1][column] != null){
top = board[row+1][column];
}
If any of the indexes are out of bounds assign them to NULL. In Candidate create a method isSameType(Candidate other);
isSameType(Candidate other)
{
if(other == null)
return false;
else
retrun getCardChar() == other.getCardChar();
}
change your if to:
if(center.isSameType(top) || center.isSameType(bottom) || ...)
{
return false;
}
As you have determined, checking [-1][0] doesn't work. But you don't need to check that non-existent slot. Just make sure you don't run off the beginning or the end of the array. Also, make sure you are performing the same math operation inside your if as in your condition:
if ((row - 1) >= 0 && (row - 1) < board.length && board[row-1][column] != null){
top = board[row-1][column]; // Use -1 to match condition.
}

Balancing check never terminates in Avl tree insertion

Writing an AVL Tree to hold generics for my data structures course; in my add() method, after actually inserting an element, I step back up through its ancestors checking their scores. For the first few additions it works, but (presumably at the point where balancing does need to be done), the loop back up the path fails to terminate. I've tried everything I can think of to make sure the root of the tree's parent isn't getting set to another node or anything like that. I'm calculating balance scores as right minus left, so positive means a tree is right-heavy and negative means left-heavy. Here's my add():
public void add(T e){
if (e == null)
return;
if (root == null) {
root = new TNode<T>(null, e);
return;
}
boolean added = false;
TNode<T> current = root;
while (current != null && added != true) { //insertion loop
if (current.compareTo(e) == 0)
return;
else if (current.compareTo(e) < 0) {
if (current.getRight() == null) {
current.setRight(new TNode<T>(current, e));
added = true;
}
else
current = current.getRight();
}
else if (current.compareTo(e) > 0) {
if (current.getLeft() == null) {
current.setLeft(new TNode<T>(current, e));
added = true;
}
else
current = current.getLeft();
}
}
if (useAVL == false)
return;
//balancing, checking up from added node to find where tree is unbalanced; currently loop does not terminate
//current is now parent of inserted node
while (current.hasParent()) {
if (current.getAvl() > 1) {
if (current.getRight().getAvl() > 0)
current = rotateLeft(current);
else if (current.getRight().getAvl() < 0) {
current.setRight(rotateRight(current.getRight()));
current = rotateLeft(current);
}
}
if (current.getAvl() < -1) {
if (current.getLeft().getAvl() < 0)
current = rotateRight(current);
else if (current.getLeft().getAvl() > 0) {
current.setLeft(rotateLeft(current.getLeft()));
current = rotateRight(current);
}
}
current = current.getParent();
}
root = current;
root.setParent(null);
}
And here's the right rotation method:
private TNode<T> rotateRight(TNode<T> old) {
TNode<T> oldRoot = old;
TNode<T> newRoot = old.getLeft();
TNode<T> rightChildNewRoot = newRoot.getRight(); //was right child of what will become root, becomes left child of old root
newRoot.setRight(oldRoot);
oldRoot.setParent(newRoot);
oldRoot.setLeft(rightChildNewRoot);
if (rightChildNewRoot != null)
rightChildNewRoot.setParent(oldRoot);
newRoot.setParent(oldRoot.getParent());
return newRoot;
}

Categories