I have a binary tree program that sorts smaller/equal numbers to the left of the parent, and larger numbers to the right of the parent, and I want to print out a diagram of it, but I don't know how to print it so it formats well. Also, should the print method be part of the TreeDriver class, or part of the TreeNode class to recursively access every node.
Here are the classes:
TreeDriver:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
/**
* This class serves as the driver for a generic TreeNode, giving it the type of Integer.
*/
public class TreeDriver
{
//region Instance Variables
TreeNode<Integer> root;
//endregion
//region Constructors
public TreeDriver() throws FileNotFoundException
{
fill();
System.out.println("Count: " + root.getCount());
}
//endregion
//region Public Methods
public void fill() throws FileNotFoundException
{
Scanner reader = new Scanner(new File("TreeValueSource"));
String temp;
Integer entry;
makeRoot();
while (reader.hasNext())
{
temp = reader.nextLine();
if (temp.contains("//"))
{
if (reader.hasNext())
temp = reader.nextLine();
else break;
}
else if (checkInt(temp))
{
entry = new Integer(temp);
root.add(entry);
}
else System.out.println("ERROR IN FILL");
}
}
private void makeRoot()
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter a root value(default 50): ");
String input = scan.next();
if (checkInt(input))
root = new TreeNode<>(new Integer(input));
else
root = new TreeNode<>(50);
}
public void printCount()
{
System.out.println(root.getCount());
}
//endregion
//region Private Methods
private boolean checkInt(String candidate)
{
boolean parsable = true;
try
{
Integer.parseInt(candidate);
} catch (NumberFormatException e)
{
parsable = false;
}
return parsable;
}
//endregion
}
TreeNode:
public class TreeNode<T extends Comparable<T>>
{
//region Instance Variables
//Links
private TreeNode<T> leftChild; //Left Link
private TreeNode<T> rightChild; //Right Link
//Properties
private T data; //Info Stored by the TreeNode
private int childCount; //Number of Children
private int depth; //Level of the Node in the Tree
//endregion
//region Constructors
public TreeNode(T data, int parentDepth)
{
leftChild = null;
rightChild = null;
childCount = 0;
depth = parentDepth + 1;
this.data = data;
}
public TreeNode(T data)
{
leftChild = null;
rightChild = null;
childCount = 0;
depth = 0;
this.data = data;
System.out.println("A Root was Created");
}
//endregion
//region Public Methods
/**
* ADD
* Adds a new TreeNode to the tree. Left if equal or smaller, Right if larger
*
* #param data The data held by the TreeNode
* #see TreeNode
*/
public void add(T data)
{
if (this.data.compareTo(data) <= 0)
{
addLeft(data);
} else if (this.data.compareTo(data) > 0)
{
addRight(data);
} else
{
System.out.println("ERROR IN TREENODE.ADD");
}
}
public int getCount()
{
return count();
}
/**
* IS LEAF
* Determines if the current node has no children
*
* #return True if no children, False otherwise
*/
public boolean isLeaf()
{
return childCount == 0;
}
//endregion
//region Private Methods
//Adds the data to the left of this.TreeNode
private void addLeft(T data)
{
if (null == leftChild)
{
leftChild = new TreeNode(data, depth);
childCount += 1;
} else
leftChild.add(data);
}
//Adds the data to the right of this.TreeNode
private void addRight(T data)
{
if (null == rightChild)
{
rightChild = new TreeNode(data, depth);
childCount += 1;
} else
rightChild.add(data);
}
/**
* COUNT
* Recursively counts the number of TreeNodes
*
* #return the number of TreeNodes, 0 if an error
*/
private int count()
{
if (isLeaf())
{
return 1;
} else if (childCount == 2)
{
return 1 + leftChild.count() + rightChild.count();
} else if (null == leftChild)
{
return 1 + rightChild.count();
} else if (null == rightChild)
{
return 1 + leftChild.count();
} else
{
System.out.println("ERROR IN COUNT AT DEPTH " + depth);
return 0;
}
}
//endregion
}
You can use this answer as a model
[How to print binary tree diagram?
Modifying the BtreePrinter Class. And no you shouldn't put the print method in the TreeDriver class.
class Node<T extends Comparable<?>> {
Node<T> left, right;
T data;
public Node(T data) {
this.data = data;
}
}
class BTreePrinter {
public static <T extends Comparable<?>> void printNode(Node<T> root) {
int maxLevel = BTreePrinter.maxLevel(root);
printNodeInternal(Collections.singletonList(root), 1, maxLevel);
}
private static <T extends Comparable<?>> void printNodeInternal(List<Node<T>> nodes, int level, int maxLevel) {
if (nodes.isEmpty() || BTreePrinter.isAllElementsNull(nodes))
return;
int floor = maxLevel - level;
int endgeLines = (int) Math.pow(2, (Math.max(floor - 1, 0)));
int firstSpaces = (int) Math.pow(2, (floor)) - 1;
int betweenSpaces = (int) Math.pow(2, (floor + 1)) - 1;
BTreePrinter.printWhitespaces(firstSpaces);
List<Node<T>> newNodes = new ArrayList<Node<T>>();
for (Node<T> node : nodes) {
if (node != null) {
System.out.print(node.data);
newNodes.add(node.left);
newNodes.add(node.right);
} else {
newNodes.add(null);
newNodes.add(null);
System.out.print(" ");
}
BTreePrinter.printWhitespaces(betweenSpaces);
}
System.out.println("");
for (int i = 1; i <= endgeLines; i++) {
for (int j = 0; j < nodes.size(); j++) {
BTreePrinter.printWhitespaces(firstSpaces - i);
if (nodes.get(j) == null) {
BTreePrinter.printWhitespaces(endgeLines + endgeLines + i + 1);
continue;
}
if (nodes.get(j).left != null)
System.out.print("/");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(i + i - 1);
if (nodes.get(j).right != null)
System.out.print("\\");
else
BTreePrinter.printWhitespaces(1);
BTreePrinter.printWhitespaces(endgeLines + endgeLines - i);
}
System.out.println("");
}
printNodeInternal(newNodes, level + 1, maxLevel);
}
private static void printWhitespaces(int count) {
for (int i = 0; i < count; i++)
System.out.print(" ");
}
private static <T extends Comparable<?>> int maxLevel(Node<T> node) {
if (node == null)
return 0;
return Math.max(BTreePrinter.maxLevel(node.left), BTreePrinter.maxLevel(node.right)) + 1;
}
private static <T> boolean isAllElementsNull(List<T> list) {
for (Object object : list) {
if (object != null)
return false;
}
return true;
}
}
Related
Can someone help me with the interval search in binary tree.
I understand how to check left side of the tree,but I have troubles with chicking right side of it.
This is my code by now.
private boolean search(BSTNode r, int from,int till){
boolean found = false;
int arr[];
arr=new int[10];
int i=0;
while (r != null)
{
int rval = r.getData();
if (from < rval && till >rval) {
r = r.getLeft();
arr[i]=rval;
i++;
}else
r=r.getRight();
}
return found;
}
This is full class of BSTNode.
From and till it is range of interval(from
class BSTNode
{
BSTNode left, right;
int data;
/* Constructor */
public BSTNode()
{
left = null;
right = null;
data = 0;
}
/* Constructor */
public BSTNode(int n)
{
left = null;
right = null;
data = n;
}
/* Function to set left node */
public void setLeft(BSTNode n)
{
left = n;
}
/* Function to set right node */
public void setRight(BSTNode n)
{
right = n;
}
/* Function to get left node */
public BSTNode getLeft()
{
return left;
}
/* Function to get right node */
public BSTNode getRight()
{
return right;
}
You can search by using queue like this:
public boolean search(Integer from, Integer till) {
return search(root, from, till);
}
private boolean search(BSTNode root, Integer from, Integer till) {
boolean found = false;
Queue<BSTNode> queue = new ArrayDeque<>();
queue.add(root);
List<Integer> list = new ArrayList<>();
while (!queue.isEmpty()) {
BSTNode node = queue.poll();
int data = node.getData();
if (from < data && till > data) {
found = true;
list.add(data);
}
if (node.getLeft() != null)
queue.add(node.getLeft());
if (node.getRight() != null)
queue.add(node.getRight());
}
System.out.println(list);
return found;
}
, full code
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
// Tree building...
tree.insert(50);
tree.insert(40);
tree.insert(20);
tree.insert(10);
tree.insert(50);
System.out.println(tree.search(10, 30));
}
static class BinarySearchTree {
private BSTNode root;
public void insert(Integer item) {
root = insert(root, item);
}
private BSTNode insert(BSTNode node, Integer item) {
if (node == null) {
return new BSTNode(item);
} else if (item.compareTo(node.data) == 0) {
return node;
} else if (item.compareTo(node.data) < 0) {
node.setRight(insert(node.r, item));
return node;
} else {
node.setLeft(insert(node.l, item));
return node;
}
}
public Integer find(Integer target) {
return find(root, target);
}
private Integer find(BSTNode node, Integer target) {
if (node == null) {
return null;
}
Integer cmd = target.compareTo(node.data);
if (cmd == 0) {
return node.data;
} else if (cmd < 0) {
return find(node.getRight(), target);
} else {
return find(node.getLeft(), target);
}
}
public boolean search(Integer from, Integer till) {
return search(root, from, till);
}
private boolean search(BSTNode root, Integer from, Integer till) {
boolean found = false;
Queue<BSTNode> queue = new ArrayDeque<>();
queue.add(root);
List<Integer> list = new ArrayList<>();
while (!queue.isEmpty()) {
BSTNode node = queue.poll();
int data = node.getData();
if (from < data && till > data) {
found = true;
list.add(data);
}
if (node.getLeft() != null)
queue.add(node.getLeft());
if (node.getRight() != null)
queue.add(node.getRight());
}
System.out.println(list);
return found;
}
}
static class BSTNode {
Integer data;
BSTNode l = null;
BSTNode r = null;
public BSTNode(Integer data) {
super();
this.data = data;
}
public Integer getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BSTNode getLeft() {
return l;
}
public void setLeft(BSTNode l) {
this.l = l;
}
public BSTNode getRight() {
return r;
}
public void setRight(BSTNode r) {
this.r = r;
}
#Override
public String toString() {
return "BSTNode [data=" + data + ", l=" + l + ", r=" + r + "]";
}
}
, the output
[20]
true
So I am trying to implement BST (Binary Search Tree) I have made an add method which adds TreeNodes to an tree[TreeNode] array
Here is the TreeNode class where I'm trying to set the parent as well as the left and right nodes, I inspected with a debugger and I'm not sure why but it is not setting the Parent var and also it only add one or the other in the leftChild and rightChild fields.
The setter in question is this one
//set parent
public void setParent(TreeNode t)
{
this.parent = t.parent;
}
I cant understand when i call it from the PAS43DEPQ class it does not set properly.
class TreeNode implements Comparable<TreeNode>
{
private Integer value;
private TreeNode leftChild;
private TreeNode rightChild;
private TreeNode parent;
//constructors
public TreeNode(){}
public TreeNode(Integer v){this.value = v;}
public TreeNode(TreeNode t){
this.value = t.value;
this.parent = t.parent;
this.leftChild = t.leftChild;
this.rightChild = t.rightChild;
}
public TreeNode (Comparable c){this.value = (int) c;}
//set parent
public void setParent(TreeNode t)
{
this.parent = t.parent;
}
//get parent
public TreeNode getParent()
{
return this.parent;
}
//get value
public int getValue(){return value;}
//set value
public void setValue(Integer i){ this.value = i;}
//get left node
public TreeNode getLeftChild(){return leftChild;}
//get right node
public TreeNode getRightChild(){return rightChild;}
//set left child
public void setLeftChild(TreeNode t) {this.leftChild = t;}
//set right child
public void setRightChild(TreeNode t) {this.rightChild = t;}
public TreeNode find(int n)
{
//this statement runs if the current node is == the value being searched.
if(this.value == n)
return this;
//this returns values left of the root then performs a recursive call if not found
if(value < this.value && leftChild != null)
return leftChild.find(n);
//this does the same as above except looks on the right side of the root
if(rightChild != null)
return rightChild.find(n);
//this returns if value is not found
return null;
}
#Override
public int compareTo(TreeNode o)
{
if (this.value == o.value)
{
return 0;// if value equal
}
if (this.value > o.value) //if value greater
{
return 1;
}
if (this.value < o.value)
{
return -1; //if value less
}
return 99;
}
}
Here is the class where I add from:
public class PAS43DEPQ implements DEPQ
{
private TreeNode[] tree = new TreeNode[100];
int index = 0;
#Override
public Comparable inspectLeast() {
return null;
}
#Override
public Comparable inspectMost() {
return null;
}
/*
right: (2 * n) + 2
left: (2 * n) + 1
parent: (1 - n) / 2
*/
public int right()
{
return (2 * index) + 2;
}
public int left()
{
return (2 * index) + 1;
}
public int parent()
{
return Math.round((index - 1) / 2);
}
#Override
public void add(Comparable c)
{
// Root node
if (tree[0] == null) {
tree[0] = new TreeNode(c);
return;
}
//this while loop is for tree traversal
while(tree[index] != null) {
if( c.compareTo(tree[index].getValue()) == 0) {
index += right() - index;
continue;
}
if( c.compareTo(tree[index].getValue()) > 0) {
index += right() - index;
continue;
}
if( c.compareTo(tree[index].getValue()) < 0) {
index += left() - index;
continue;
}
}
//this part is for place the new node
if(tree[index] == null) {
tree[index] = new TreeNode(c);
tree[index].setParent(tree[parent()]);
if( c.compareTo(tree[index].getValue()) == 0)
tree[parent()].setRightChild(tree[index]);
if( c.compareTo(tree[index].getValue()) > 0)
tree[parent()].setRightChild(tree[index]);
if( c.compareTo(tree[index].getValue()) < 0)
tree[parent()].setLeftChild(tree[index]);
index = 0;
}
return;
}
#Override
public Comparable getLeast() {
return null;
}
#Override
public Comparable getMost() {
return null;
}
#Override
public boolean isEmpty() {
return (tree[0] == null) ? true : false;
}
#Override
public int size() {
return tree.length;
}
}
I cant seam to work out why the parent isnt being set the the the line
"tree[index].setParent(tree[parent()])"
is being called? any ides on why this is happening?
The set method should be like this
//set parent
public void setParent(TreeNode t)
{
this.parent = t;
}
This method will make TreeNode t as the parent of the Current Node referenced by this.
The statement which you are using sets parent of TreeNode t as the parent of the current node.
I am a java developer ( but from a NON CS/IT educational background). I have developed interest in algorithms and currently I am trying to implement Prim's Algorithm for Calculating MST. This I have told in order to let you know the context but my question is independent of MST.
I have implemented my own MinHeap instead of using Java.util.PriorityQueue (although even when I changed my code and used it I was facing the same problem that I have mentioned ahead).
I add items to the heap but the value of the item deciding the comparison can change even after the items have been added in the heap. Now once the value changes the heap is not changed and hence upon removing the item I get wrong item popped out.
How to tackle this situation..
I am pasting my code for reference. I am adding items of type Vertex in my MinHeap. Each Vertex has an 'int cost' associated which is used to compare two objects of Vertex. Now I add object of Vertex in the heap and heap is adjusted as per current value of 'cost' but once an object of Vertex is added then if its cost is changed then I want help as how to adjust and get it reflected in my Heap. Please help me in this regards and also please correct me if I am going in wrong direction.
public class MSTRevisited {
public static void main(String[] args) {
Graph graph = new Graph(6);
graph.addNode('a');
graph.addNode('b');
graph.addNode('c');
graph.addNode('d');
graph.addNode('e');
graph.addNode('f');
graph.addEdege('a', 'b', 4);
graph.addEdege('a', 'f', 2);
graph.addEdege('b', 'f', 3);
graph.addEdege('b', 'c', 6);
graph.addEdege('c', 'f', 1);
graph.addEdege('c', 'd', 3);
graph.addEdege('d', 'e', 2);
graph.addEdege('f', 'e', 4);
graph.applyPrimAlgo();
}
public static class Graph {
private Vertex verticies[];
private int maxSize;
private int size;
private HashMap map;
private MinHeap Q;
public Graph(int maxSize) {
this.maxSize = maxSize;
verticies = new Vertex[maxSize];
map = new HashMap(maxSize);
Q = new MinHeap(maxSize);
}
public void addNode(char data) {
verticies[size] = new Vertex(data, size);
map.put(data, size);
size++;
}
public void addEdege(char sourceData, char destinationData, int weight) {
int sourceIndex = map.get(sourceData);
int destinationIndex = map.get(destinationData);
verticies[sourceIndex].adj = new Neighbour(destinationIndex, weight,
verticies[sourceIndex].adj);
verticies[destinationIndex].adj = new Neighbour(sourceIndex,weight,
verticies[destinationIndex].adj);
}
public void applyPrimAlgo() {
// add all the keys to the Q
PrimEdege pe = null;
Vertex vertex = verticies[0];
vertex.cost = 0;
vertex.state = Vertex.IN_Q;
Q.add(vertex);
while(!Q.isEmpty()){
Vertex poppedVertex = Q.remove();
poppedVertex.state = Vertex.VISITED;
Neighbour temp = poppedVertex.adj;
while(temp != null){
Vertex adjVertex = verticies[temp.index];
if(adjVertex.state != Vertex.VISITED){
if(poppedVertex.parentIndex != -1){
char source = verticies[poppedVertex.index].data;
char destination = verticies[adjVertex.index].data;
pe = new PrimEdege(source, destination, pe);
}
if(adjVertex.cost > temp.weight){
adjVertex.cost = temp.weight;
adjVertex.parentIndex = poppedVertex.index;
}
if(adjVertex.state != Vertex.IN_Q){
Q.add(adjVertex);
}
}
temp = temp.next;
}
}
PrimEdege temp = pe;
while(temp != null){
System.out.print("("+temp.source+","+temp.destination+") ");
temp = temp.next;
}
System.out.println();
}
private static class PrimEdege{
public char source;
public char destination;
private PrimEdege next;
public PrimEdege(char source, char destination, PrimEdege next){
this.source = source;
this.destination = destination;
this.next = next;
}
}
public static class MinHeap {
private Vertex[] items;
private int maxSize;
private int size;
public MinHeap(int maxSize) {
this.maxSize = maxSize;
items = new Vertex[maxSize];
}
public void add(Vertex item) {
items[size] = item;
heapifyAfterAdd();
size++;
}
private void swap(int index1, int index2) {
Vertex temp = items[index1];
items[index1] = items[index2];
items[index2] = temp;
}
private void heapifyAfterAdd() {
int currIndex = size;
Vertex currItem = items[currIndex];
int parentIndex = currIndex / 2;
Vertex parentItem = items[parentIndex];
while (currItem.compareTo(parentItem) == -1) {
swap(parentIndex, currIndex);
currIndex = parentIndex;
currItem = items[currIndex];
parentIndex = currIndex / 2;
parentItem = items[parentIndex];
}
}
public Vertex remove() {
Vertex vertex = items[0];
swap(0, size - 1);
items[size-1] = null;
size--;
heapifyAfterRemove();
return vertex;
}
private void heapifyAfterRemove() {
int currIndex = 0;
Vertex currItem = items[currIndex];
int childIndex;
Vertex childItem;
int left = 2 * currIndex + 1;
int right = 2 * currIndex + 2;
if (left > size - 1) {
return;
}
if (right > size - 1) {
childIndex = left;
} else if (items[left].compareTo(items[right]) == -1) {
childIndex = left;
} else {
childIndex = right;
}
childItem = items[childIndex];
while (childItem.compareTo(currItem) == -1) {
swap(currIndex, childIndex);
currIndex = childIndex;
currItem = items[currIndex];
left = 2 * currIndex + 1;
right = 2 * currIndex + 2;
if (left > size - 1) {
return;
}
if (right > size - 1) {
childIndex = left;
} else if (items[left].compareTo(items[right]) == -1) {
childIndex = left;
} else {
childIndex = right;
}
childItem = items[childIndex];
}
}
public boolean isEmpty() {
return size == 0;
}
}
public static class HashMap {
private MapNode[] map;
private char[] keySet;
private int maxSize;
private int size;
public HashMap(int maxSize) {
this.maxSize = maxSize;
map = new MapNode[maxSize];
keySet = new char[maxSize];
}
private static class MapNode {
char key;
int value;
MapNode next;
public MapNode(char key, int value, MapNode next) {
this.key = key;
this.value = value;
this.next = next;
}
}
public int hash(char key) {
return 31 * key;
}
public int getmapIndexOfkey(char key) {
return hash(key) % maxSize;
}
public void put(char key, int value) {
int index = getmapIndexOfkey(key);
map[index] = new MapNode(key, value, map[index]);
keySet[index] = key;
size++;
}
public int get(char key) {
int index = getmapIndexOfkey(key);
MapNode temp = map[index];
while (temp != null) {
if (temp.key == key) {
break;
}
}
if (temp != null) {
return temp.value;
} else {
return -1;
}
}
public char[] keyset() {
return keySet;
}
}
public static class Vertex {
public static final int NEW = 0;
public static final int IN_Q = 1;
public static final int VISITED = 2;
private int state = NEW;
private int cost = Integer.MAX_VALUE;
private char data;
private Neighbour adj;
private int index;
private int parentIndex = -1;
public int compareTo(Vertex other) {
if (cost < other.cost) {
return -1;
}
if (cost > other.cost) {
return 1;
}
return 0;
}
public Vertex(char data, int index) {
this.data = data;
this.index = index;
}
public void addAdjacentVertex(Neighbour adj) {
this.adj = adj;
}
public void updateCost(int newCost, int parentIndex){
this.cost = newCost;
this.parentIndex = parentIndex;
}
}
public static class Neighbour {
private Neighbour next;
private int index;
private int weight;
public Neighbour(int index,int weight, Neighbour next) {
this.next = next;
this.index = index;
this.weight = weight;
}
}
}
}
Thanks friends for investing time to my question, but I figured that I had few mistakes in my implementation due to which I was getting wrong answer.
I corrected the state of the vertex when it is added to the MinHeap
I corrected the logic of outputting the edge of MST and I got the correct answer....
Most important as Suggested by Karthik (many thanks to him) to remove and re-add the item whose 'cost' changes while it being in the heap. I actually applied bubble up approach instead of removing and again adding which worked !!
After modifying above 3 points my code is working as I expect it to work.
Also #Karthik I do not have two methods for before and after remove but rather I have one for when I add an item ( in the last and I use the method heapifyAfterAdd() and other for when I remove the 1st item then I use heapifyAfterRemove() )
Please find below my code after corrections.
public class MSTRevisited {
public static void main(String[] args) {
Graph graph = new Graph(6);
/*
* graph.addNode('a'); graph.addNode('b'); graph.addNode('c');
* graph.addNode('d'); graph.addNode('e'); graph.addNode('f');
* graph.addEdege('a', 'b', 4); graph.addEdege('a', 'f', 2);
* graph.addEdege('b', 'f', 3); graph.addEdege('b', 'c', 6);
* graph.addEdege('c', 'f', 1); graph.addEdege('c', 'd', 3);
* graph.addEdege('d', 'e', 2); graph.addEdege('f', 'e', 4);
*/
graph.addNode('a');
graph.addNode('b');
graph.addNode('c');
graph.addNode('d');
graph.addEdege('a', 'b', 4);
graph.addEdege('a', 'c', 2);
graph.addEdege('b', 'c', 1);
graph.addEdege('b', 'd', 2);
graph.addEdege('c', 'd', 3);
graph.applyPrimAlgo();
}
public static class Graph {
private Vertex verticies[];
private int maxSize;
private int size;
private HashMap map;
private MinHeap Q;
public Graph(int maxSize) {
this.maxSize = maxSize;
verticies = new Vertex[maxSize];
map = new HashMap(maxSize);
Q = new MinHeap(maxSize);
}
public void addNode(char data) {
verticies[size] = new Vertex(data, size);
map.put(data, size);
size++;
}
public void addEdege(char sourceData, char destinationData, int weight) {
int sourceIndex = map.get(sourceData);
int destinationIndex = map.get(destinationData);
verticies[sourceIndex].adj = new Neighbour(destinationIndex,
weight, verticies[sourceIndex].adj);
verticies[destinationIndex].adj = new Neighbour(sourceIndex,
weight, verticies[destinationIndex].adj);
}
public void applyPrimAlgo() {
// add all the keys to the Q
PrimEdege pe = null;
Vertex vertex = verticies[0];
vertex.cost = 0;
vertex.state = Vertex.IN_Q;
Q.add(vertex);
while (!Q.isEmpty()) {
Vertex poppedVertex = Q.remove();
poppedVertex.state = Vertex.VISITED;
Neighbour temp = poppedVertex.adj;
if (poppedVertex.parentIndex != -1) {
char source = verticies[poppedVertex.index].data;
char destination = verticies[poppedVertex.parentIndex].data;
pe = new PrimEdege(source, destination, pe);
}
while (temp != null) {
Vertex adjVertex = verticies[temp.index];
if (adjVertex.state != Vertex.VISITED) {
if (adjVertex.cost > temp.weight) {
adjVertex.cost = temp.weight;
adjVertex.parentIndex = poppedVertex.index;
}
if (adjVertex.state != Vertex.IN_Q) {
Q.add(adjVertex);
adjVertex.state = Vertex.IN_Q;
} else {
// bubble up this Node in the heap
Q.bubbleUp(adjVertex);
}
}
temp = temp.next;
}
}
PrimEdege temp = pe;
while (temp != null) {
System.out.print("(" + temp.source + "," + temp.destination
+ ") ");
temp = temp.next;
}
System.out.println();
}
private static class PrimEdege {
public char source;
public char destination;
private PrimEdege next;
public PrimEdege(char source, char destination, PrimEdege next) {
this.source = source;
this.destination = destination;
this.next = next;
}
}
public static class MinHeap {
private Vertex[] items;
private int maxSize;
private int size;
public MinHeap(int maxSize) {
this.maxSize = maxSize;
items = new Vertex[maxSize];
}
public void bubbleUp(Vertex vertex) {
// #TODO
int i = 0;
for (; i < size; i++) {
if (items[i] == vertex) {
break;
}
}
if (i < size) {
int currentIndex = i;
Vertex currentItem = items[currentIndex];
int parentIndex = (currentIndex-1) / 2;
Vertex parentItem = items[parentIndex];
while (currentItem.compareTo(parentItem) == -1) {
swap(currentIndex, parentIndex);
currentIndex = parentIndex;
currentItem = items[currentIndex];
parentIndex = (currentIndex-1) / 2;
parentItem = items[parentIndex];
}
}
}
public void add(Vertex item) {
items[size] = item;
heapifyAfterAdd();
size++;
}
private void swap(int index1, int index2) {
Vertex temp = items[index1];
items[index1] = items[index2];
items[index2] = temp;
}
private void heapifyAfterAdd() {
int currIndex = size;
Vertex currItem = items[currIndex];
int parentIndex = (currIndex-1) / 2;
Vertex parentItem = items[parentIndex];
while (currItem.compareTo(parentItem) == -1) {
swap(parentIndex, currIndex);
currIndex = parentIndex;
currItem = items[currIndex];
parentIndex = (currIndex-1) / 2;
parentItem = items[parentIndex];
}
}
public Vertex remove() {
return remove(0);
}
public Vertex remove(Vertex vertex) {
int i = 0;
for (; i < size; i++) {
if (items[i] == vertex) {
break;
}
}
if (i < size) {
return remove(i);
}
return null;
}
private Vertex remove(int index) {
Vertex vertex = items[index];
swap(index, size - 1);
items[size - 1] = null;
size--;
heapifyAfterRemove(index);
return vertex;
}
private void heapifyAfterRemove(int index) {
int currIndex = index;
Vertex currItem = items[currIndex];
int childIndex;
Vertex childItem;
int left = 2 * currIndex + 1;
int right = 2 * currIndex + 2;
if (left > size - 1) {
return;
}
if (right > size - 1) {
childIndex = left;
} else if (items[left].compareTo(items[right]) == -1) {
childIndex = left;
} else {
childIndex = right;
}
childItem = items[childIndex];
while (childItem.compareTo(currItem) == -1) {
swap(currIndex, childIndex);
currIndex = childIndex;
currItem = items[currIndex];
left = 2 * currIndex + 1;
right = 2 * currIndex + 2;
if (left > size - 1) {
return;
}
if (right > size - 1) {
childIndex = left;
} else if (items[left].compareTo(items[right]) == -1) {
childIndex = left;
} else {
childIndex = right;
}
childItem = items[childIndex];
}
}
public boolean isEmpty() {
return size == 0;
}
}
public static class HashMap {
private MapNode[] map;
private char[] keySet;
private int maxSize;
private int size;
public HashMap(int maxSize) {
this.maxSize = maxSize;
map = new MapNode[maxSize];
keySet = new char[maxSize];
}
private static class MapNode {
char key;
int value;
MapNode next;
public MapNode(char key, int value, MapNode next) {
this.key = key;
this.value = value;
this.next = next;
}
}
public int hash(char key) {
return 31 * key;
}
public int getmapIndexOfkey(char key) {
return hash(key) % maxSize;
}
public void put(char key, int value) {
int index = getmapIndexOfkey(key);
map[index] = new MapNode(key, value, map[index]);
keySet[index] = key;
size++;
}
public int get(char key) {
int index = getmapIndexOfkey(key);
MapNode temp = map[index];
while (temp != null) {
if (temp.key == key) {
break;
}
}
if (temp != null) {
return temp.value;
} else {
return -1;
}
}
public char[] keyset() {
return keySet;
}
}
public static class Vertex {
public static final int NEW = 0;
public static final int IN_Q = 1;
public static final int VISITED = 2;
private int state = NEW;
private int cost = Integer.MAX_VALUE;
private char data;
private Neighbour adj;
private int index;
private int parentIndex = -1;
public int compareTo(Vertex other) {
if (cost < other.cost) {
return -1;
}
if (cost > other.cost) {
return 1;
}
return 0;
}
public Vertex(char data, int index) {
this.data = data;
this.index = index;
}
public void addAdjacentVertex(Neighbour adj) {
this.adj = adj;
}
public void updateCost(int newCost, int parentIndex) {
this.cost = newCost;
this.parentIndex = parentIndex;
}
}
public static class Neighbour {
private Neighbour next;
private int index;
private int weight;
public Neighbour(int index, int weight, Neighbour next) {
this.next = next;
this.index = index;
this.weight = weight;
}
}
}
}
I am having trouble with my swap method in the Quick Sort program. I'm implementing it from a QuickSort method that sorts arrays. Here I take in a file with an integer on each line, it puts the number in a doubly linked list and then sorts the list and outputs to a new file. I need help with the swap method and what else I need to add or do to make it work properly. Any advise would help and examples are best. Thank you
//swap A[pos1] and A[pos2]
public static void swap(DList A, int pos1, int pos2){
int temp = A.get(pos1);
A[pos1] = A[pos2];
A[pos2] = temp;
}
My entire program for quicksort looks like this:
import java.util.*;
import java.io.*;
public class Test_QuickSort{
private static Scanner input = new Scanner(System.in);
private static DList list = new DList();
public static void main(String[] args) throws FileNotFoundException
{
input = new Scanner(new File("data.txt"));
while (input.hasNext())
{
String s = input.nextLine();
DNode g = new DNode(Integer.parseInt(s));
list.addLast(g);
}
//int[] A = {1,4,6,2};
QuickSort(list, 0, list.size()-1);
//for(int i = 0; i < A.length; i++)
// System.out.print(A[i] + " ");
}
public static void QuickSort(DList A, int left, int right){
if(left >= right)
return;
int pivot_index = partition(A, left, right);
QuickSort(A, left, pivot_index - 1);
QuickSort(A, pivot_index + 1, right);
}
public static int partition(DList A, int left, int right){
int pivot = A.get(right);
int index = left;
for(int i = left; i < right; i++){
if(A.get(i) <= pivot){
swap(A, index, i);
index ++;
}
}
swap(A, index, right);
return index;
}
//swap A[pos1] and A[pos2]
public static void swap(DList A, int pos1, int pos2){
int temp = A.get(pos1);
A[pos1] = A[pos2];
A[pos2] = temp;
}
}
My DList Method looks like this:
class DNode {
protected int element; // String element stored by a node
protected DNode next, prev; // Pointers to next and previous nodes
public DNode(int e)
{
element = e;
prev = null;
next = null;
}
public DNode()
{
element = 0;
next = null;
prev = null;
}
public DNode(int e, DNode p, DNode n) {
element = e;
prev = p;
next = n;
}
public int getElement() {
return element; }
public DNode getPrev() {
return prev; }
public DNode getNext() {
return next; }
public void setElement(int newElem) { element = newElem; }
public void setPrev(DNode newPrev) { prev = newPrev; }
public void setNext(DNode newNext) { next = newNext; }
}
public class DList {
protected int size;
protected DNode header, trailer;
public DList() {
size = 0;
header = new DNode(0, null, null);
trailer = new DNode(0, header, null);
header.setNext(trailer);
}
public int size() {
return size; }
public boolean isEmpty() {
return (size == 0); }
public DNode getFirst() throws IllegalStateException {
if (isEmpty()) throw new IllegalStateException("List is empty");
return header.getNext();
}
public DNode getLast() throws IllegalStateException {
if (isEmpty()) throw new IllegalStateException("List is empty");
return trailer.getPrev();
}
public DNode getPrev(DNode v) throws IllegalArgumentException {
if (v == header) throw new IllegalArgumentException
("Cannot move back past the header of the list");
return v.getPrev();
}
public int get(int pos)
{
DNode current = new DNode();
for(int i = 0; i <= pos && current != null; i++)
{
if(pos == 0){
current = header;
}
else{
current = current.next;
break;
}
}
return current.element;
}
public DNode getNext(DNode v) throws IllegalArgumentException {
if (v == trailer) throw new IllegalArgumentException
("Cannot move forward past the trailer of the list");
return v.getNext();
}
public void addBefore(DNode v, DNode z) throws IllegalArgumentException {
DNode u = getPrev(v); // may throw an IllegalArgumentException
z.setPrev(u);
z.setNext(v);
v.setPrev(z);
u.setNext(z);
size++;
}
public void addAfter(DNode v, DNode z) {
DNode w = getNext(v); // may throw an IllegalArgumentException
z.setPrev(v);
z.setNext(w);
w.setPrev(z);
v.setNext(z);
size++;
}
public void addFirst(DNode v) {
addAfter(header, v);
}
public void addLast(DNode v) {
addBefore(trailer, v);
}
public boolean hasPrev(DNode v) {
return v != header; }
public boolean hasNext(DNode v) {
return v != trailer; }
public String toString() {
String s = "[";
DNode v = header.getNext();
while (v != trailer) {
s += v.getElement();
v = v.getNext();
if (v != trailer)
s += ",";
}
s += "]";
return s;
}
}
The reason you are always retrieving the same element in DList.get is that you stop looping after the first iteration. Simply remove the break-statement, and the loop should work as intended.
public int get(int pos)
{
DNode current = new DNode();
for(int i = 0; i <= pos && current != null; i++)
{
if(pos == 0){
current = header;
}
else{
current = current.next;
// break; <-- remove this
}
}
return current.element;
}
Side note: You could get rid of the if-statement, if you would initialize current to header:
public int get(int pos)
{
DNode current = header;
for(int i = 1; i <= pos && current != null; i++)
{
current = current.next;
}
return current.element;
}
Now regarding your swap-method: As already stated, you try to treat the instance of DList as an array by trying to dereference an element using square-brackets. Instead, you should implement a method in DList that allows setting an element at a certain position. For example:
public void setAt(int pos, int value){
DNode current = header;
for(int i = 1; i <= pos && current != null; i++){
current = current.next;
}
if(current != null)
current.setElement(value);
else
throw new IndexOutOfBoundsException();
}
Now you can change your swap-method to:
public static void swap(DList a, int pos1, int pos2){
int temp = a.get(pos1);
a.setAt(pos1, a.get(pos2));
a.setAt(pos2, temp);
}
The depth first search does not function properly. Honestly I am not sure if this is the current way of implementation. I am new to implementing graph and want to be a pro at it.
Where am I going wrong and I do not understand how do I print the elements either in the dfs() function so I can know how dfs should be like.
Would getter & setter method for child elements is recommended?
Here is my code:
package graphs;
public enum State {
Unvisited,Visiting,Visited;
}
package graphs;
public class Node {
public Node[] adjacent;
public int adjacentCount;
private String vertex;
public graphs.State state;
public Node(String vertex)
{
this.vertex = vertex;
}
public Node(String vertex, int adjacentlen)
{
this.vertex = vertex;
adjacentCount = 0;
adjacent = new Node[adjacentlen];
}
public void addAdjacent(Node adj)
{
if(adjacentCount < 30)
{
this.adjacent[adjacentCount] = adj;
adjacentCount++;
}
}
public Node[] getAdjacent()
{
return adjacent;
}
public String getVertex()
{
return vertex;
}
}
public class Graph {
public int count; // num of vertices
private Node vertices[];
public Graph()
{
vertices = new Node[8];
count = 0;
}
public void addNode(Node n)
{
if(count < 10)
{
vertices[count] = n;
count++;
}
else
{
System.out.println("graph full");
}
}
public Node[] getNode()
{
return vertices;
}
}
package graphs;
import java.util.Stack;
import graphs.State;
public class Dfs {
/**
* #param args
*/
static boolean visited[];
public void dfs(Node root)
{
if(root == null) return;
Stack<Node> s = new Stack<Node>();
s.push(root);
root.state = State.Visited;
System.out.println("root:"+root.getVertex() + "\t");
while(!s.isEmpty())
{
Node u = s.pop();
for(Node n: u.getAdjacent())
{
if(n.state != State.Visited)
{
dfs(n);
}
}
}
}
public static Graph createNewGraph()
{
Graph g = new Graph();
Node[] temp = new Node[8];
temp[0] = new Node("A", 3);
temp[1] = new Node("B", 3);
temp[2] = new Node("C", 1);
temp[3] = new Node("D", 1);
temp[4] = new Node("E", 1);
temp[5] = new Node("F", 1);
temp[0].addAdjacent(temp[1]);
temp[0].addAdjacent(temp[2]);
temp[0].addAdjacent(temp[3]);
temp[1].addAdjacent(temp[0]);
temp[1].addAdjacent(temp[4]);
temp[1].addAdjacent(temp[5]);
temp[2].addAdjacent(temp[0]);
temp[3].addAdjacent(temp[0]);
temp[4].addAdjacent(temp[1]);
temp[5].addAdjacent(temp[1]);
for (int i = 0; i < 7; i++)
{
g.addNode(temp[i]);
}
return g;
}
public static void main(String[] args) {
Graph g = createNewGraph();
Dfs s = new Dfs();
//Node[] n = g.getNode();
s.dfs(g.getNode()[0]);
}
}
You don't need stack here. Only recursion:
public void dfs(Node node) {
if (node == null) {
return;
}
System.out.println("Node: " + node.getVertex());
node.state = State.Visited;
for (Node n : node.getAdjacent()) {
if (n.state != State.Visited) {
dfs(n);
}
}
}
UPDATE
To check path existence:
public boolean isPath(Graph graph, Node start, Node target) {
for (Node node : graph.getNode()) {
if (node != null) {
node.state = State.Unvisited;
}
}
dfs(start);
return target.state == State.Visited;
}