So I'm trying to write a RR Rotation and LL Rotation with Java for an AVL tree. I have most of it figured out, however I don't know where I should modify the height within the method. I've been trying to understand it for a few days here but I cannot figure out where exactly it would go in the method I currently have. If someone could help explain exactly where I should put the modifications for the height of the node (it uses getLeft/setLeft for it's left height and getRight/setRight for it's right height) it would be extremely helpful!
/**
* Performs a right shift of the current critical node. (Left rotation)
* #precond Tree is not empty.
* #return a tree with the updated rotation.
**/
public BinaryNodeAVL280<I> shiftLeftRotation(BinaryNodeAVL280<I> critNode)
{
if(this.rootNode() == null)
{
throw new ContainerEmpty280Exception("Cannot rotate an empty AVL tree!");
}
//TempNode becomes right of A (which is C)
BinaryNodeAVL280<I> tempNode = (BinaryNodeAVL280<I>) critNode.rightNode();
//Set the parent of tempNode (A) to be critNode's parent.
tempNode.setParent(critNode.getParent());
//Set critNode (A)'s left Node (which is B) to tempNode's leftNode (C's left which is D)
critNode.setRightNode(tempNode.leftNode());
//Check if the rightNode of A is null.
if(critNode.rightNode() != null)
{
//If not null, set A's right parent (C's parent) to current parent.
((BinaryNodeAVL280<I>) critNode.rightNode()).setParent(critNode);
}
//Set Left node of C (was D) to critNode (A)
tempNode.setLeftNode(critNode);
//Set critNode's (unknown for now) to temp node (C).
critNode.setParent(tempNode);
//If parent of C is not null.
if(tempNode.getParent() != null)
{
//If the right child of tempNode is the same as critNode
if(tempNode.getParent().rightNode() == critNode)
//Set the right child to tempNode.
tempNode.getParent().setRightNode(tempNode);
//If the child of temp node's left side is equal to critNode
else if(tempNode.getParent().leftNode() == critNode)
//Set temp node's left to tempNode(b)
tempNode.getParent().setLeftNode(tempNode);
}
//increment height somehow...
return tempNode;
}
Related
I have to develop a Dijkstra Alogirthm in Java and I have a question to Dijkstra in a circle.
So for a Tree or a normal graph without a loop it works.
So I have a Status White means not found, gray = found but not dealt with and black means done.
So when I have a loop I tryed a if (next.status == Node.Black) but then he didn't found all nodes.
So the question is, how can I add a loop detection and found all nodes?
Thanks for help and tips
best regards
witar7
PS: the if (next.equals(startNode) was only an idea to stop the loop.
public void populateDijkstraFrom(Node startNode) {
this.resetState();
PriorityQueue<Node> distanceQueue = new PriorityQueue<Node>();
for (int x = 0; x < nodes.size(); x++) { // for each node
nodes.get(x).distance = Double.POSITIVE_INFINITY; // set distance to inf
nodes.get(x).predecessor = null; // delete existing predecessors
}
startNode.distance = 0.0; // set distance from startNode to zero
startNode.status = Node.GRAY; // mark startNode as active
Node current = startNode;
distanceQueue.add(current); // add startNode to prio queue
while (!distanceQueue.isEmpty()) { // while contains elements
current = distanceQueue.poll(); // set current to head of queue
current.status = Node.BLACK; // mark head as settled
for (Node next : current.getAdjacentNodes() ) { // get all adjacent nodes
if (next.equals(startNode)) {
break;
}
next.status = Node.GRAY;
// stopExecutionUntilSignal();// mark status as found
distanceQueue.add(next);
if (distanceQueue.contains(next)) {
if (next.distance > current.distance + current.getWeight(next)) { // if the found distance is smaller then the existing one
next.predecessor = current; // change distance in node
next.distance = current.distance + current.getWeight(next); // set predecessor
}
}
}
}
this.clearMarks();
}
PS: the if (next.equals(startNode) was only an idea to stop the loop.
There's no need to do this, your while condition will terminate anyway when it can't find anymore unvisited adjacent nodes. You just have to check whether current visited node status is BLACK and if yes, don't add it to the queue (it's already been visited before).
P.S.: I don' think you need GRAY status, just BLACK or WHITE. Deal with the node right away, no need to delay.
I'm creating a drawing application, where the user clicks on a button to select which shape to draw - node for example - and then the shape is placed where the mouse is clicked .
I want the user to be able to click on two different "shapes" on the screen to create a link between them.
Every node I create is added to an ArrayList of Nodes. I have a for-loop to iterate through the nodes, and I created a function contains in my class NODE:
boolean contains(Point point) {
if((point.x >= centerX-radius) && (point.x <= centerX+radius) &&
(point.y <= centerY+radius) && (point.y>=centerY-radius))
return true;
else
return false;
}
because component.contains(point) did not work, and I think I'm able to get the first node that's clicked, but I'm still struggling with identifying to two clicks the other node.
Any help would be appreciated.
I think you need to keep an additional variable, to know if the click is first or second.. In this case, it might be useful to keep the Node selected with first click..
So, in pseudo-code:
Node selected;
onClick() {
Node clicked = findNode();
if (clicked == null || clicked == selected) {
selected = null;
} else
if (selected == null) {
selected = clicked;
} else {
createLine(selected, clicked);
selected = null;
}
}
To get mouse coordinates, getX() and getY() functions are used inside the onmouseClicked(MouseEvent me) function.
I'm trying to convert a 2-3-4 Tree into a Red-Black tree in java, but am having trouble figuring it out.
I've written these two basic classes as follows, to make the problem straightforward, but can't figure out where to go from here.
public class TwoThreeFour<K> {
public List<K> keys;
public List<TwoThreeFour<K>> children;
}
public class RedBlack<K> {
public K key;
public boolean isBlack;
public RedBlack<K> left,right;
public RedBlack<K key, boolean isBlack, RedBlack<K> left, RedBlack<K> right){
this.key = key; this.isBlack = isBlack; this.left = left; this.right = right;
}
}
I'm assuming the 2-3-4 tree is valid, and want to return a red black tree when the method is called.
I've also tried the following code with no luck:
public convert(TwoThreeFour<K> tTF){
if (ttf.keys.size() == 3)
RedBlack<K> node = RedBlack<ttf.keys[1], true, RedBlack<ttf.keys[0], false, /* not sure what to put here for left */, /* not sure what to put here for right */), RedBlack<ttf.keys[2], false, /* not sure what to put here for left */, /* not sure what to put here for right */)
etc. for keys.size() == 2, 1....
I know it has to be recursive in theory, but am having a hard time figuring it out. Any thoughts?
Consider these three rules:
Transform any 2-node in the 2-3-4 tree into a black node in the
red-black tree.
Transform any 3-node into a child node and a parent node. The
child node has two children of its own: either W and X or X and Y.
The parent has one other child: either Y or W. It doesn’t matter
which item becomes the child and which the parent. The child is
colored red and the parent is colored black.
Transform any 4-node into a parent and two children, the first
child has its own children W and X; the second child has children Y
and Z. As before, the children are colored red and the parent is
black.
The red-black rules are automatically satisfied if you follow these rules. Here's the resulting example tree after applying the transformations.
Hopefully that should get you going. For easy to understand and detailed explanation, you can refer to Robert Lafore's Data Structures book.
I am using a JTree in which new nodes needs to be inserted dynamically to the root(consider adding children to root). Once the user selects a node and clicks a button, the new node needs to be added after the selected node. If none of the node is selected then it adds the new node at the end of the tree. Below is my code
public void addNodeToRoot(TestCase testCase) {
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(testCase.toString());
int currentNoOfChildren = getTcBuilderTree().getModel().getChildCount(getTcBuilderTree().getModel().getRoot());
TreePath currentSelection = getTcBuilderTree().getSelectionPath();
int currentIndex=0;
//if the user has not selected a node add the test case at the end of the tree
if (currentSelection == null) {
currentIndex = currentNoOfChildren;
}
//if user has selected a node then insert the new node after the selected node
else {
int[] currentSelectedIndex = getTcBuilderTree().getSelectionRows();
currentIndex = currentSelectedIndex[0];
}
treeModel.insertNodeInto(childNode, getRoot(), currentIndex);
}
it works all fine but the code gives an exception when there are child nodes in the level 3 as well. The reason is when the tree has more levels and when its expanded then the currentIndex gives unexpected number (it counts all the indexes in all levels up from the root to the selected node) and the app gives ArrayIndexOutOfBoundsException since the currentIndex becomes greater than currentNoOfChildren
If the tree is not expanded then everything happens correctly. Please let me know how to resolve this. Is there any other way to get the no of children of a specific level in the tree?
Maybe code below can resolve your problem.
int currentNoOfChildren = getTcBuilderTree().getVisibleRowCount();
I am trying to implement a breadth first traversal for a maze. This is the code I have so far using a linked list but I am not sure if it is searching breadth first. Is this the proper way to do it? any suggestions, comments?
public boolean traverseBreadth(){
//traverse the floor from entrance to exit
//stepping only on red tiles
steps = new LinkedList<Tile>();
possibleSteps = new LinkedList<Tile>();
//reset markings
reset();
//push the entrance onto the stack
entrance.setVisited();
steps.add(entrance);
System.out.println("add " + entrance);
nextMoves(entrance);
//keep going as long as we have a possibility to move
//and we haven't reached the end yet
while (!possibleSteps.isEmpty()&& (!possibleSteps.getLast().equals(exit)))
{
Tile x = possibleSteps.removeLast();
x.setMarked(); //walked on that square
steps.add(x); //walk to that square
System.out.println("Walked to the square " + x);
//now figure out where you can walk from this square
nextMoves(x);
try {
Thread.currentThread().sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
if (possibleSteps.getLast().equals(exit)){
steps.push(possibleSteps.removeLast());
System.out.println("made it from entrance to exit");
System.out.println(steps.toString());
return true;
}
else
{ JOptionPane.showMessageDialog(null,"sorry can't reach the exit");
return false;
}
}
This isn't a breadth first search - this is depth first.
There are 2 places that are obviously depth first
you remove from the end of the frontier (possibleTiles), not the beginning.
you do not have a traversal hierarchy (parent to child) to rebuild the traversal path, only a single "path" with tiles. Therefore, it is depth first.
Things to change:
instead of LinkedList, change that to Dictionary. The key of the dictionary will be the tile, and the value will be the tile's parent. Use this to reconstruct your final path.
your "moveNext" function is probably right. Make sure it is pushing to the end of the List.
do not pop (getLast()) from PossibleSteps. PossibleSteps should be a First-In-First-Out queue. Retrieve the first Tile of PossibleSteps (this will explore the tiles closest to the start first).
Things to improve:
instead of using Tile to track exploration, use a Set (call it ExploredTile) where you put tiles that you have traversed)
use a Queue instead of List.
Some C#/Pseudo Code (cuz I'm not at an IDE)
Dictionary<Tile,Tile> path = ...;
Queue<Tile> frontier = ...;
Set<Tile> explored = ...;
path[start] = null;
while(frontier.Count > 0){
var tile = frontier.Dequeue();
if(explored.Contains(tile)){
continue;
}
explored.add(tile);
if (Tile == Exit){
rebuildPath(Exit);
}else{
for (Tile t in Tile.neighbours){
if (!explored.Contains(t)){
frontier.Enqueue(t);
path[t] = tile; // Set the path hierarchy
}
}
}
}
RebuildPath
LinkedList<Tile> finalPath = ...;
Tile parent = path[exitTile];
finalPath.push(exitTile);
while(parent != null){
finalPath.push(parent);
parent = path[parent];
}
finalPath.reverse();
Hopefully I got it right... :)