I have been trying to work on a linked list implementation I thought I had it nailed, but for some reason I can't work out how to add a new node to the list at the start of the list.
This was a polynomial addition method, everything else works as expected, but this section does not work as expected. It returns polynomial with no changes... I think I am missing something really simple but cant see it.
else if (power > polynomial.powerMax())
{
Polynomial newlink = new Polynomial(coefficient,power);
newlink.successor = polynomial;
polynomial = newlink;
}
Whole Method
public class Polynomial
{
final static private int mantissa = 52;
final static private double epsilon = Math.pow(2.0, -mantissa);
private double coefficient = 0.0;
private int power = 0;
private Polynomial successor=null;
public Polynomial(double coefficient, int power)
{
if (Double.isNaN(coefficient)) return;
if (Math.abs(coefficient) < epsilon) return;
if (power<0) return;
this.coefficient=coefficient;
this.power=power;
}
public static void add(Polynomial polynomial, double coefficient, int power)
{
if (polynomial == null) return;
if (Math.abs(coefficient) < epsilon) coefficient = 0.0;
if (coefficient == 0.0) return;
if (power < 0) return;
if (power < polynomial.powerMin())
{
Polynomial newNode = new Polynomial(coefficient,power);
if (polynomial.successor != null)
{
while (polynomial.successor != null)
{
polynomial.successor = polynomial.successor.successor;
}
polynomial.successor = newNode;
}
else if (polynomial.successor == null )
polynomial.successor = newNode;
}
else if (power > polynomial.powerMax())
{
Polynomial newlink = new Polynomial(coefficient,power);
newlink.successor = polynomial;
polynomial = newlink;
}
else
{
if (power == polynomial.power)
polynomial.coefficient = polynomial.coefficient + coefficient;
}
}
In Java the references of variables are passed by value (link). That means if you assign anything new to the variable polynomial it will not have any effect outside of this method.
String x = "Foo";
public void change (String s) {
s="Bar";
}
System.out.println(x);
change(x);
System.out.println(x);
Will print
Foo
Foo
You need to return the new Polynomial you created from the add method.
public static Polynomial add(Polynomial polynomial, double coefficient, int power) {
...
return polynomial;
}
Related
Hello there I am learning Java and after doing some tasks to learn recursion I was giving my self some exercises to learn it a bit more but now I am struggeling with some..
So the main Problem is that I dont know how I can multiply every element in an Array recursively when the elements in that array are object (Maybe there is at the end no difference if objects are in there or not). So the exercise I gave myself was: check if 1 / 3 is in the given Array. If Yes then multiply everything in that array with 2 / 1.
This is Fraction:
private int numerator; // Zaehler
private int denominator; // Nenner
public Fraction ( int num, int denom )
{
if ( denom != 0 )
{
if ( denom < 0 )
{
numerator = -num;
denominator = -denom;
}
else
{
numerator = num;
denominator = denom;
}
reduce();
}
else
{
// error: division by zero
throw new IllegalArgumentException();
}
}
public Fraction()
{
numerator = 0;
denominator = 1;
}
public Fraction( int num )
{
numerator = num;
denominator = 1;
}
So I got it done by doing it with an for loop:
public static Fraction[] mulWithFor(Fraction[] arr)
{
for (int i = 0; i<arr.length; i++)
{
arr[i] = arr[i].multiply(new Fraction(2,1));
}
return arr;
}
But thats not my Main goal I want to do it recursively so that was my approach:
public static Fraction[] mulAus(Fraction[] arr, int i)
{
if (i>= 0 && i<arr.length)
{
rekurMul(arr,i);
//return mulAus(rekurMul(arr,i-1));
}
return arr;
}
public static Fraction rekurMul(Fraction[] arr, int i)
{
if (i>= 0 && i<arr.length)
{
return arr[i].multiply(new Fraction(2,1));
return arr[i].multiply(new Fraction(2, 1)); // Does Not Work!!!
}
throw new IndexOutOfBoundsException();
}
Maybe there is someone who can Help me! Thank you for your attention.
OK Thanks to #Chaï Sarfati and also to the others trying to help me out. I now know how to multiply recursive things in an Array! I used the Methods from #Chaï Sarfati but wrote an alternative method for his "oneThirdIsPresent" which is also a recursive method : So now my working code looks like this
public static Fraction[] mulAus(Fraction[] arr)
{
if(contains(arr,arr.length-1,new Fraction(1,3)))
{
rekurMul(arr,0);
return arr;
}
throw new IllegalArgumentException("1/3 does not exist in the Input-Array");
}
public static void rekurMul(Fraction[] arr, int i)
{
if(i == arr.length)
{
return ;
}
arr[i] = arr[i].multiply(new Fraction(2,1));
rekurMul(arr,i+1);
}
The Method to check if 1 / 3 exists in the given Array.
public static boolean contains(Fraction[] arr, int i, Fraction x)
{
if (i>= 0 && i < arr.length)
{
if (arr[i].equals(x))
{ return true;}
else
{ return contains(arr, i-1,x); }
}
return false;
}
I hope other People can learn from the code.. Maybe there are better solutions but I am just starting Programming so I dont know them for now.
Bye
Assuming you have a multiplyBy(Fraction f) method that works properly in you Fraction class.
Moreover, it will be better (more readable, more time & space complexity saving) to do it iteratively.
For the sake of the example, I would do like this:
First define:
private static boolean oneThirdIsPresent(Fraction[] arr){
for (int i = 0; i < arr.length; i++) {
if(arr[i].numerator == 1 && arr[i].denominator == 3) {
return true;
}
}
return false;
}
private static void recursivelyMultBy2(Fraction[] arr, int index){
if(index == arr.length){
return;
}
arr[index] = arr[index].multiplyBy(new Fraction(2));
recursivelyMultBy2(arr, index+1);
}
In order to solve finally:
public static void multBy2IfOneThirdIsPresent(Fraction[] arr){
if(oneThirdIsPresent(arr)){
recursivelyMultBy2(arr, 0);
}else{
return;
}
}
Here's a quick example of just the recursive multiplication part:
public static void main(String[] args)
{
Fraction[] fractions = new Fraction[] {new Fraction(1,2), new Fraction(2,3), new Fraction(3,1)};
System.out.println("Fractions:");
for(Fraction f: fractions)
{
System.out.println(f);
}
System.out.println("Multiplying array by 2...");
Fraction.mulAus(fractions, new Fraction(2, 1));
for(Fraction f: fractions)
{
System.out.println(f);
}
}
Modified Fraction Class (multiplication code at the bottom):
public class Fraction
{
private int numerator; // Zaehler
private int denominator; // Nenner
public Fraction(int num, int denom)
{
if (denom != 0)
{
if (denom < 0)
{
numerator = -num;
denominator = -denom;
}
else
{
numerator = num;
denominator = denom;
}
reduce();
}
else
{
// error: division by zero
//throw new IllegalArgumentException();
}
}
private void reduce()
{
// ...
}
public Fraction()
{
numerator = 0;
denominator = 1;
}
public Fraction(int num)
{
numerator = num;
denominator = 1;
}
public String toString()
{
return numerator + " / " + denominator;
}
public void MultiplyBy(Fraction F)
{
if (F != null)
{
numerator = numerator * F.numerator;
denominator = denominator * F.denominator;
reduce();
}
}
public static void mulAus(Fraction[] arr, Fraction F)
{
if(arr != null && F != null)
{
rekurMul(arr, 0, F);
}
}
private static void rekurMul(Fraction[] arr, int i, Fraction F)
{
arr[i].MultiplyBy(F);
if (i < (arr.length - 1))
{
rekurMul(arr, ++i, F);
}
}
}
Output:
I have run into a problem converting pseudocode of Dijkstras algorithm into actual code. I was given and adjacency list such as "Location - adjacent location - distance to location," example for one node: AAA AAC 180 AAD 242 AAH 40.
My task was to read a file organized as adjacency list as described, and compute the shortest path from one node to another.
Here is the Dijkstra pseudocode:
void dijkstra( Vertex s )
{
for each Vertex v
{
v.dist = INFINITY;
v.known = false;
}
s.dist = 0;
while( there is an unknown distance vertex )
{
Vertex v = smallest unknown distance vertex;
v.known = true;
for each Vertex w adjacent to v
if( !w.known )
{
DistType cvw = cost of edge from v to w;
if( v.dist + cvw < w.dist )
{
// Update w
decrease( w.dist to v.dist + cvw );
w.path = v;
}
}
}
}
im having the most trouble with the line "for each Vertex w adjacent to v"
Here is my nonworking code:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class Dijkstra {
public static boolean isInteger(String s) {
return isInteger(s, 10);
}
public static boolean isInteger(String s, int radix) {
if (s.isEmpty())
return false;
for (int i = 0; i < s.length(); i++) {
if (i == 0 && s.charAt(i) == '-') {
if (s.length() == 1)
return false;
else
continue;
}
if (Character.digit(s.charAt(i), radix) < 0)
return false;
}
return true;
}
public static void dijkstra(Vertex[] a, Vertex s, int lineCount) {
int i = 0;
while (i < (lineCount)) // each Vertex v
{
a[i].dist = Integer.MAX_VALUE;
a[i].known = false;
i++;
}
s.dist = 0;
int min = Integer.MAX_VALUE; //
while (!(a[0].known == true && a[1].known == true && a[2].known == true && a[3].known == true
&& a[4].known == true && a[5].known == true && a[6].known == true && a[7].known == true
&& a[8].known == true && a[9].known == true && a[10].known == true && a[11].known == true
&& a[12].known == true)) {
System.out.println("here");
for (int b = 0; b < lineCount; b++) {
if (a[b].dist < min && a[b].known == false) {
min = a[b].dist;
}
}
int c = 0;
while (c < lineCount) {
if (a[c].dist == min && a[c].known == false) {
break;
}
c++;
}
System.out.println(min);
a[c].known = true;
int adjSize = a[c].adj.size();
int current = 0;
System.out.println(adjSize);
while (current < adjSize - 1) {
String currentAdjacent = (String) a[c].adj.get(current);
int p = 0;
while (p < lineCount) {
if (a[p].name.equals(currentAdjacent)) {
if (!a[p].known) {
String cvwString = (String) a[c].distance.get(current);
int cvw = Integer.parseInt(cvwString);
System.out.println(" This is cvw" + cvw);
System.out.println("Here2");
if (a[c].dist + cvw < a[p].dist) {
a[p].dist = a[c].dist + cvw;
a[p].path = a[c];
}
}
}
p++;
}
current++;
}
}
}
public static class Vertex {
public List adj; // Adjacency list
public List distance;
public boolean known;
public int dist; // DistType is probably int
public Vertex path;
public String name;
// Other fields and methods as needed
}
public static void printPath(Vertex v) {
if (v.path != null) {
printPath(v.path);
System.out.print(" to ");
}
System.out.print(v);
}
public static void main(String[] args) throws IOException {
int lineCounter = 0;
BufferedReader br = new BufferedReader(new FileReader("airport.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
lineCounter = lineCounter + 1;
}
Vertex[] arr = new Vertex[lineCounter];
for (int i = 0; i < lineCounter; i++) {
arr[i] = new Vertex();
arr[i].adj = new LinkedList<String>();
arr[i].distance = new LinkedList<Integer>();
}
;
//
int arrayCounter = 0;
String everything = sb.toString();
String[] lines = everything.split("\\s*\\r?\\n\\s*");
for (String line1 : lines) {
arr[arrayCounter] = new Vertex();
arr[arrayCounter].adj = new LinkedList<String>();
arr[arrayCounter].distance = new LinkedList<Integer>();
String[] result = line1.split("\\s+");
for (int x = 0; x < result.length; x++) {
if (x == 0) {
arr[arrayCounter].name = result[0];
continue;
} else if (isInteger(result[x])) {
arr[arrayCounter].distance.add(result[x]);
continue;
} else {
arr[arrayCounter].adj.add(result[x]);
continue;
}
}
arrayCounter++;
}
for (int i = 0; i < 12; i++) {
System.out.println(arr[i].name);
}
System.out.println(lineCounter);
dijkstra(arr, arr[3], lineCounter - 1);
printPath(arr[11]);
} finally {
br.close();
}
}
}
Using my vertex class as is I was using a series of while loops to first, traverse the adjacency strings stored in a linked list while comparing to see which vertex is equivalent to the adjacency list string. Is there a better way to code "for each Vertex w adjacent to v" using my Vertex class? And apologies ahead for messy code and any others style sins i may have committed. Thanks!
To solve this problem you need a bunch of "Node" objects, stored in a HashMap, keyed on Source Location.
In the node, you need a collection of references to adjacent "Node" objects (or at least their "key" so you can write logic against it. The "Node" also needs to know it's location and distance to each "adjacent" node. Think Lundon Underground Tube Maps - each station connects to at least one other station. Usually two or more. Therefore, adjacent nodes to tube stations are the immediate next stops you can get to from that station.
Once you have that data structure in place, you can then use a recursive routine to iterate through each individual node. It should then iterate through each child node (aka adjacent node), and track distances from the initial (source) node to the current node by storing this data in a HashMap and using the current accumulated distance whilst recursing (or "walking" the graph"). This tracking information should be part of your method signature when recursing. You will also need to track the current path you have taken when recursing, in order to avoid circular loops (which will ultimately and ironically cause a StackOverflowError). You can do this by using a HashSet. This Set should track the source and current node's location as the entry key. If you see this present during your recursion, then you have already seen it, so don't continue processing.
I'm not going to code the solution for you because I suspect that you ask more specific questions as you work your way through understanding the answer, which are very likely answered elsewhere.
I'm quite new to pathfinding and recently got A-Star working for the first time in Java with Libgdx, but it has some flaws, it doesnt always find the fastest path , or the program simply kills itself(because it's too slow?) :/
(Input/Output here: Imgur album: White = untouched Node, green = start, red = target, blue = path, yellow = node is on closed list but unrelevant)
The rest of the code can be found on Github.
This is the code for the Algorithm itself:
Node lastNode;
Node[] neighborNodes;
int lowestF = 2000;
Node bestNode;
public void findPath() {
for(int x = 0; x < map.worldWidth; x++) {
for(int y = 0; y < map.worldHeight; y++) {
nodes[x][y].calculateHeuristic(targetNode);
}
}
lastNode = startNode;
while(lastNode != targetNode || !openList.isEmpty()) {
neighborNodes = map.getNeighbors(lastNode);
for(Node node:neighborNodes) {
if(node != null)
if(node.state != State.BLOCKED && !closedList.contains(node)) {
openList.add(node);
node.parentNode = lastNode;
}
}
lowestF = 1000;
for(Node node:openList) {
if(node.f <= lowestF) {
lowestF = node.f;
bestNode = node;
}
}
if(openList.isEmpty() && bestNode != targetNode) {
System.out.println("No Path possible");
return;
}
openList.remove(bestNode);
closedList.add(bestNode);
lastNode = bestNode;
lastNode.setState(State.SEARCHED);
}
reconstructPath();
}
public void reconstructPath() {
Node lastNode = targetNode;
while(lastNode != startNode) {
lastNode = lastNode.parentNode;
lastNode.setState(State.PATH);
}
setStartAndEnd();
}
And the Node Class:
public class Node {
public enum State {
NORMAL, BLOCKED, START, END, SEARCHED, PATH
}
public State state;
int xPos, yPos;
Color color;
Node parentNode;
int f;
int movementCost = 10;
int heuristic;
public Node(int x, int y) {
xPos = x;
yPos = y;
setState(State.NORMAL);
}
public void setState(State newState) {
state = newState;
}
public boolean isNodeClicked() {
int inputX = Gdx.input.getX();
int inputY = Gdx.graphics.getHeight() - Gdx.input.getY();
if(inputX > xPos*32 && inputX < xPos*32+32 &&
inputY > yPos*32 && inputY < yPos*32+32) {
return true;
}
return false;
}
public void calculateHeuristic(Node targetNode) {
heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos-targetNode.yPos))) * movementCost;
f = movementCost+heuristic;
}
public int calculateHeuristic(Node finishNode, int useless) {
return (Math.abs((xPos-finishNode.xPos)) + Math.abs((yPos-finishNode.yPos))) * movementCost;
}
}
At the moment I'm using a 2-dimensional array for the map or nodes and Arraylist for open and closed list.
It'd be much appreciated if somebody could help me get my A-star to behave and explain to me what I did wrong, I would also be very grateful for any other criticism, since I want to improve my programming :)
Thanks for your help in Advance :)
Your problem is here:
public void calculateHeuristic(Node targetNode) {
heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos- targetNode.yPos))) * movementCost;
f = movementCost+heuristic;
}
Your calculation of your heuristic is wrong, because your calculation of your movementCost is wrong. The cost of a node is not a fixed value. It's the summation of all of the costs to move between nodes along the path to that node so far. So your node should actually have a function,
public int calculateCost(){
if(parentNode != null){
return movementCost + parentNode.calculateCost();
} else{
return movementCost;
}
}
And your heuristic thus becomes:
public void calculateHeuristic(Node targetNode) {
heuristic = (Math.abs((xPos-targetNode.xPos)) + Math.abs((yPos- targetNode.yPos))) * movementCost;
f = calculateCost()+heuristic;
}
Your other problems look like they probably all come from the various typos/logical errors I mentioned in the comments (while(...||openSet.isEmpty()) instead of while(...|| !openSet.isEmpty()), etc)
I have written a program that creates nodes that in this class are parts of polynomials and then the two polynomials get added together to become one polynomial (list of nodes). All my code compiles so the only problem I am having is that the nodes are not inserting into the polynomial via the insert method I have in polynomial.java and when running the program it does create nodes and displays them in the 2x^2 format but when it comes to add the polynomials together it displays o as the polynomials, so if anyone can figure out whats wrong and what I can do to fix it it would be much appreciated.
Here is the code:
import java.util.Scanner;
class Polynomial{
public termNode head;
public Polynomial()
{
head = null;
}
public boolean isEmpty()
{
return (head == null);
}
public void display()
{
if (head == null)
System.out.print("0");
else
for(termNode cur = head; cur != null; cur = cur.getNext())
{
System.out.println(cur);
}
}
public void insert(termNode newNode)
{
termNode prev = null;
termNode cur = head;
while (cur!=null && (newNode.compareTo(cur)<0))
{
prev = null;
cur = cur.getNext();
}
if (prev == null)
{
newNode.setNext(head);
head = newNode;
}
else
{
newNode.setNext(cur);
prev.setNext(newNode);
}
}
public void readPolynomial(Scanner kb)
{
boolean done = false;
double coefficient;
int exponent;
termNode term;
head = null; //UNLINK ANY PREVIOUS POLYNOMIAL
System.out.println("Enter 0 and 0 to end.");
System.out.print("coefficient: ");
coefficient = kb.nextDouble();
System.out.println(coefficient);
System.out.print("exponent: ");
exponent = kb.nextInt();
System.out.println(exponent);
done = (coefficient == 0 && exponent == 0);
while(!done)
{
Polynomial poly = new Polynomial();
term = new termNode(coefficient,exponent);
System.out.println(term);
poly.insert(term);
System.out.println("Enter 0 and 0 to end.");
System.out.print("coefficient: ");
coefficient = kb.nextDouble();
System.out.println(coefficient);
System.out.print("exponent: ");
exponent = kb.nextInt();
System.out.println(exponent);
done = (coefficient==0 && exponent==0);
}
}
public static Polynomial add(Polynomial p, Polynomial q)
{
Polynomial r = new Polynomial();
double coefficient;
int exponent;
termNode first = p.head;
termNode second = q.head;
termNode sum = r.head;
termNode term;
while (first != null && second != null)
{
if (first.getExp() == second.getExp())
{
if (first.getCoeff() != 0 && second.getCoeff() != 0);
{
double addCoeff = first.getCoeff() + second.getCoeff();
term = new termNode(addCoeff,first.getExp());
sum.setNext(term);
first.getNext();
second.getNext();
}
}
else if (first.getExp() < second.getExp())
{
sum.setNext(second);
term = new termNode(second.getCoeff(),second.getExp());
sum.setNext(term);
second.getNext();
}
else
{
sum.setNext(first);
term = new termNode(first.getNext());
sum.setNext(term);
first.getNext();
}
}
while (first != null)
{
sum.setNext(first);
}
while (second != null)
{
sum.setNext(second);
}
return r;
}
}
Here is my Node class:
class termNode implements Comparable
{
private int exp;
private double coeff;
private termNode next;
public termNode(double coefficient, int exponent)
{
coeff = coefficient;
exp = exponent;
next = null;
}
public termNode(termNode inTermNode)
{
coeff = inTermNode.coeff;
exp = inTermNode.exp;
}
public void setData(double coefficient, int exponent)
{
coefficient = coeff;
exponent = exp;
}
public double getCoeff()
{
return coeff;
}
public int getExp()
{
return exp;
}
public void setNext(termNode link)
{
next = link;
}
public termNode getNext()
{
return next;
}
public String toString()
{
if (exp == 0)
{
return(coeff + " ");
}
else if (exp == 1)
{
return(coeff + "x");
}
else
{
return(coeff + "x^" + exp);
}
}
public int compareTo(Object other)
{
if(exp ==((termNode) other).exp)
return 0;
else if(exp < ((termNode) other).exp)
return -1;
else
return 1;
}
}
And here is my Test class to run the program.
import java.util.Scanner;
class PolyTest{
public static void main(String [] args)
{
Scanner kb = new Scanner(System.in);
Polynomial r;
Polynomial p = new Polynomial();
System.out.println("Enter first polynomial.");
p.readPolynomial(kb);
Polynomial q = new Polynomial();
System.out.println();
System.out.println("Enter second polynomial.");
q.readPolynomial(kb);
r = Polynomial.add(p,q);
System.out.println();
System.out.print("The sum of ");
p.display();
System.out.print(" and ");
q.display();
System.out.print(" is ");
r.display();
}
}
A few suggestions:
Class names by convention starts with uppercase, e.g. TermNode
Use generics, i.e. TermNode implements Comparable<TermNode>
In fact, it's probably even better to have Node<Term> instead
Bugs I saw:
prev = null; in insert
Should be prev = cur;
Consider factoring this out to a helper find-like method
In readPolynomial, you're creating a new Polynomial every iteration, and doesn't do anything to this.
You want to either insert terms into this, or keep one Polynomial that you return at the end of a static readPolynomial method
while (first != null) sum.setNext(first);
What are you trying to accomplish here? This is an infinite loop!
More suggestions:
It may be easier/more readable/etc to do add in two passes:
merge polynomials first, making sure terms are properly ordered
3x+1 and 2x+2 merges to 3x+2x+1+2
Then simplify by merging any consecutive pairs of terms that have the same exponent
3x+2x simplifies to 5x
Once you get it working, consider optimizing it to add in one pass if necessary
In fact, the polynomial merging can be done easily in O(N^2) using insert
Get it correct first, optimize to O(N) later
While debugging/developing, print out the polynomials often. Do it after you read it. Do it after insertion. Do it after the first pass of add. Do it after the second pass.
One bug I can see right away is: while traversing the list you need to save the current node cur to prev before you move on so. But you are assigning null to prev all the time:
while (cur!=null && (newNode.compareTo(cur)<0)) {
prev = null;// <---- should be prev = cur;
cur = cur.getNext();
My issue is more semantic than functional, As the code does seem to implement the deQueue and enQueue functions correctly.
The reheapDown and reheapUp functions are being used incorrectly, And i believe the issue lies in my heap function
package priqueue;
public class Hosheap{
private Patient[] elements;
private int numElements;
public Hosheap(int maxSize)
{
elements= new Patient[maxSize];
numElements=maxSize;
}
public void ReheapDown(int root,int bottom)
{
int maxChild;
int rightChild;
int leftChild;
leftChild=root*2+1;
rightChild=root*2+2;
if (leftChild<=bottom)
{
if(leftChild==bottom)
maxChild=leftChild;
else
{
if(elements[leftChild].getPriority() <= elements[rightChild].getPriority())
maxChild=rightChild;
else
maxChild=leftChild;
}
if(elements[root].getPriority()<elements[maxChild].getPriority())
{
Swap(root,maxChild);
ReheapDown(maxChild,bottom);
}
}
}
public void ReheapUp(int root,int bottom)
{
int parent;
if(bottom>root)
{
parent=(bottom-1)/2;
if(elements[parent].getPriority()<elements[bottom].getPriority())
{
Swap(parent,bottom);
ReheapUp(root,parent);
}
}
}
public void Swap(int Pos1, int Pos2)
{
Patient temp;
temp = elements[Pos1];
elements[Pos1]=elements[Pos2];
elements[Pos2]=temp;
}
public Patient getElement(int e)
{
return elements[e];
}
public void setElement(Patient p, int n)
{
elements[n]=p;
}
}
The idea is to rearrange a simple priority queue system so when a patient object is removed, ReheapUp or down correctly rearranges the queue, Which the code does not accomplish. Should i also include the priority queue code, Or is this already too lengthy?
I am using NetBeans IDE 6.0.1, If that helps.
Depending on your usage requirements, the answer relating to TreeSets will most probably do what you want.
However if you really need a queue, as opposed to a sorted collection, then the inbuilt PriorityQueue may be of use.
Not exactly answering your question, but with Java you may want to look into the built-in Collection classes. You can get priority queue behavior but using a TreeSet (a type of ordered-set) and implementing a custom Comparator for Patient instances. Depending what you're trying to achieve, this may be preferable. It would look something like this:
In Patient.java ...
class Patient implements Comparator {
...
public int compareTo(Patient other) {
return getPriority() > other.getPriority() ? 1 : 0;
}
Then in the place you want to use the queue
Set<Patient> queue = new TreeSet<Patient>();
queue.add(p1);
queue.add(p2);
//traverse in order of priority
for(Patient p : queue) {
doStuff();
}
Here is a simple implementation of a PriorityHeap. I coded it up pretty quick so it may have some flaws but I have implemented the pushUp() and pushDown() logic.
import java.util.Random;
public class Heap {
private Double[] data;
private int lastItem;
public Heap(int initialSize) {
// to simplify child/parent math leave the first index empty
// and use a lastItem that gives us the size
data = new Double[initialSize];
lastItem = 0;
}
public void insert(Double d) {
// double size if needed
// should have a matching shrink but this is example code
if (lastItem + 1 >= data.length) {
Double[] doubled = new Double[data.length * 2];
System.arraycopy(data, 0, doubled, 0, data.length);
data = doubled;
}
data[lastItem + 1] = d;
lastItem++;
pushUp(lastItem);
}
public void pushDown(int index) {
if (lastItem > 1) {
int leftChildIndex = index * 2;
int rightChildIndex = leftChildIndex + 1;
// assume that neither child will dominate (in priority)
// the item at index
int indexToPromote = index;
// there may not be a left child
if (leftChildIndex <= lastItem) {
Double leftChild = data[leftChildIndex];
Double tmp = data[index];
if (tmp.compareTo(leftChild) < 0) {
indexToPromote = leftChildIndex;
}
// there might not be a right child
if (rightChildIndex <= lastItem) {
Double rightChild = data[rightChildIndex];
tmp = data[indexToPromote];
if (tmp.compareTo(rightChild) < 0) {
indexToPromote = rightChildIndex;
}
}
}
// did either child dominate the item at index
// if so swap and push down again
if (indexToPromote != index) {
swap(index, indexToPromote);
pushDown(indexToPromote);
}
}
}
public void pushUp(int index) {
if (index > 1) {
// equivalent to floor((double)index/2.0d);
// if item at index is greater than its parent
// push the item up to until if finds a home
int parentIndex = index >>> 1;
Double parent = data[parentIndex];
Double item = data[index];
if (item.compareTo(parent) > 0) {
swap(parentIndex, index);
pushUp(parentIndex);
}
}
}
public Double removeTop() {
// assume size is zero then examine other cases
Double top = null;
if (lastItem > 1) {
// save the top item and take the bottom item and place it
// at the top the push the new top item down until it
// finds a home
top = data[1];
Double bottom = data[lastItem];
lastItem--;
data[1] = bottom;
pushDown(1);
} else if (lastItem == 1) {
top = data[1];
lastItem--;
}
return top;
}
public int size() {
return lastItem;
}
private void swap(int index1, int index2) {
Double temp = data[index1];
data[index1] = data[index2];
data[index2] = temp;
}
public static void main(String[] args) {
Heap heap = new Heap(4);
Random r = new Random();
for (int i = 0; i < 100000; i++) {
Double d = Double.valueOf(r.nextDouble() * 100.0d);
heap.insert(d);
}
double max = Double.MAX_VALUE;
while (heap.size() > 0) {
Double top = heap.removeTop();
if (top.doubleValue() > max) {
System.out.println("bad ordering...");
}
max = top.doubleValue();
System.out.println(max);
}
System.out.println("done...");
}
}