I have a task to find four unique elements , sum of which is defined. So I have as input data : data array of n elemeents, elements can be duplicated, and 's' is sum.
I have two cycles , first i in values [0, n-1], second j in [i+1, n]. All unique pairs of elements I save in Map , where key is sum and value is Collections of possible elements whats consists that sum. Result is collection of four unique elements of input data array. All actions I do in second cycle :
I check if I already have a differents beetween 's' and data[i]+data[j] ,
2)if I have I check , if data[i] and data[j] doesn't coinside with elements from saved pairs and add to reslut.
Add this pair data[i] + data [ j] to Map with history
I have a Memory Limit in this task and I get over it. Time limit is O(n^2). As I undestand I do some extra actions and save some unnecessary data.I created two object Fourths and Pairs , but they has only primitive fields inside so I thinK what deal is not in that
Here is my code in java:
public class SunForthFAIL {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
int s = Integer.parseInt(reader.readLine());
int[] data = new int[n];
Set<Forths> result = new HashSet<>();
Map<Integer, Set<Pair>> history = new HashMap<>();
StringTokenizer stringTokenizer = new StringTokenizer(reader.readLine());
for (int i = 0; i < n; i++) {
data[i] = Integer.parseInt(stringTokenizer.nextToken());
}
Arrays.sort(data);
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
int sum = data[i] + data[j];
int target = s - sum;
if (history.containsKey(target)) {
for (Pair historyPair : history.get(target)) {
if (historyPair.isDiff(i, j)) {
result.add(new Forths(historyPair.getiValue(), historyPair.getjValue(), data[i], data[j]));
}
}
}
if (history.containsKey(sum)) {
history.get(sum).add(new Pair(i, j, data[i], data[j]));
} else {
Set<Pair> set = new HashSet<>();
set.add(new Pair(i, j, data[i], data[j]));
history.put(data[i] + data[j], set);
}
}
}
System.out.println(result.size());
result.stream().sorted(Comparator.comparingInt(Forths::getFirst).thenComparing(Comparator.comparingInt(Forths::getSecond))).forEach(x -> System.out.println(x));
}
}
class Pair {
private int i;
private int j;
private int iValue;
private int jValue;
public int getiValue() {
return iValue;
}
public int getjValue() {
return jValue;
}
public Pair(int i, int j, int iValue, int jValue) {
this.i = i;
this.j = j;
this.iValue = iValue;
this.jValue = jValue;
;
}
public boolean isEquel(int i, int j) {
if (Math.min(iValue, jValue) == Math.min(i, j) &&
Math.max(iValue, jValue) == Math.max(i, j))
return true;
else
return false;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pair pair = (Pair) o;
if (Math.min(iValue, jValue) == Math.min(pair.iValue, pair.jValue) &&
Math.max(iValue, jValue) == Math.max(pair.iValue, pair.jValue))
return true;
else
return false;
}
#Override
public int hashCode() {
return Objects.hash(Math.min(iValue, jValue) + " " + Math.max(iValue, jValue));
}
public boolean isDiff(int i, int j) {
if (this.i == i || this.i == j || this.j == i || this.j == j)
return false;
else
return true;
}
}
class Forths {
private int first;
private int second;
private int third;
private int forth;
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
public Forths(int a, int b, int c, int d) {
int[] arr = new int[]{a, b, c, d};
Arrays.sort(arr);
this.first = arr[0];
this.second = arr[1];
this.third = arr[2];
this.forth = arr[3];
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Forths forths = (Forths) o;
return first == forths.first && second == forths.second && third == forths.third && forth == forths.forth;
}
#Override
public int hashCode() {
return Objects.hash(first, second, third, forth);
}
#Override
public String toString() {
return first + " " + second + " " + third + " " + forth;
}
}
In my case, I change the Pair object to int[2], with indexes of pair elements. And memory limit issue is resolved.
Related
I need to create an ID based on a 15x15 matrix values and since it is not possible to create an integer of size 15, I tried the following reasoning to create an ID of type double:
First I create a String with the values of the cells and while I do this, I look for the cell that has a value of 0. When I find I enter a dot "." in the String. Then I convert my String to BigDecilmal and the method I call doubleValue ().
public double generateId() {
String sid = "";
for (int i = 0; i < this.matrix[0].length; i++) {
for (int j = 0; j < matrix[1].length; j++) {
if (matrix[i][j].equals("0")) {
sid += ".";
} else {
sid += matrix[i][j];
}
}
}
System.out.println("ID: " + new BigDecimal(sid).doubleValue());
return new BigDecimal(sid).doubleValue();
}
I checked and the generated IDs are uniques.
Based on this, I tried to implement HashCode() as follows:
#Override
public int hashCode() {
long bits = doubleToLongBits(id);
int hash = (int) (bits ^ (bits >>> 32));
System.out.println("hash: " + hash);
return hash;
}
But my HashSet continues with duplicate values :(
Does anyone have a suggestion about how to do this?
~~>EDIT
Sate class:
public class State {
public double id;
public String[][] matrix;
public State() {
}
public State(String[][] matrix) {
this.matrix = createMatrix(matrix);//is created from a existing matrix
this.id = generateId();
}
#Override
public boolean equals(Object other) {
if ((other == null) || !(other instanceof State)) {
return false;
}
return ((State) other).getId().equals(this.getId()) && ((State) other).getId() == this.getId();
}
#Override
public int hashCode() {
long bits = doubleToLongBits(id);
int hash = (int) (bits ^ (bits >>> 32));
System.out.println("hash: " + hash);
return hash;
}
public String toString() {
return "Hashcode: " + this.hashCode();
}
public Double getId() {
return id;
}
public void setId(Double id) {
this.id = id;
}
public String[][] getMatrix() {
return matrix;
}
public void setMatrix(String[][] matrix) {
this.matrix = matrix;
}
public double generateId() {
String sid = "";
for (int i = 0; i < this.matrix[0].length; i++) {
for (int j = 0; j < matrix[1].length; j++) {
if (matrix[i][j].equals("0")) {
sid += ".";
} else {
sid += matrix[i][j];
}
}
}
System.out.println("ID: " + new BigDecimal(sid).doubleValue());
return new BigDecimal(sid).doubleValue();
}
private String[][] createMatrix(String[][] matriz) {
String[][] copia = new String[matriz[0].length][matriz[1].length];
for (int i = 0; i < copia[0].length; i++) {
for (int j = 0; j < copia[1].length; j++) {
copia[i][j] = matriz[i][j];
}
}
return copia;
}
your problem is in the equals method,
you have to remove the last part:
&& ((State) other).getId() == this.getId();
you are checking if the Boolean has the same reference, but they don't need the reference to be equal, it's enough that there value is equal
I would propose using the built-in methods of the Arrays class to generate a hashCode and test for equality:
#Override
public int hashCode() {
return Arrays.deepHashCode(matrix);
}
#Override
public boolean equals(Object other) {
if ((other == null) || !(other instanceof State)) {
return false;
}
State s = (State)other;
return Arrays.deepEquals(matrix, s.matrix);
}
I have been working on this problem for several hours now and I just cannot figure out what I am doing wrong here. Could anyone help point me in the right direction?
I was asked to write an Autocomplete program and I've completed everything except for this one method I cannot get working. Each term has: 1. String query and 2. long weight.
Here is the method:
public static Comparator<Term> byReverseWeightOrder() {
return new Comparator<Term>() { // LINE CAUSING PROBLEM
public int compare(Term t1, Term t2) {
if (t1.weight > t2.weight) { // LINE CAUSING PROBLEM
return -1;
} else if (t1.weight == t2.weight) {
return 0;
} else {
return 1;
}
}
};
}
My problem is that no matter how I mess with the method I always result in a NullPointerException(). Which, it points to this method (byReverseWeightOrder) as well as these two statements.
Arrays.sort(matches, Term.byReverseWeightOrder());
Term[] results = autocomplete.allMatches(prefix);
Here is the rest of the code if it can be found helpful:
Term
import java.util.Comparator;
public class Term implements Comparable<Term> {
public String query;
public long weight;
public Term(String query, long weight) {
if (query == null) {
throw new java.lang.NullPointerException("Query cannot be null");
}
if (weight < 0) {
throw new java.lang.IllegalArgumentException("Weight cannot be negative");
}
this.query = query;
this.weight = weight;
}
public static Comparator<Term> byReverseWeightOrder() {
return new Comparator<Term>() {
public int compare(Term t1, Term t2) {
if (t1.weight > t2.weight) {
return -1;
} else if (t1.weight == t2.weight) {
return 0;
} else {
return 1;
}
}
};
}
public static Comparator<Term> byPrefixOrder(int r) {
if (r < 0) {
throw new java.lang.IllegalArgumentException("Cannot order with negative number of characters");
}
final int ref = r;
return
new Comparator<Term>() {
public int compare(Term t1, Term t2) {
String q1 = t1.query;
String q2 = t2.query;
int min;
if (q1.length() < q2.length()) {
min = q1.length();
}
else {
min = q2.length();
}
if (min >= ref) {
return q1.substring(0, ref).compareTo(q2.substring(0, ref));
}
else if (q1.substring(0, min).compareTo(q2.substring(0, min)) == 0) {
if (q1.length() == min) {
return -1;
}
else {
return 1;
}
}
else {
return q1.substring(0, min).compareTo(q2.substring(0, min));
}
}
};
}
public int compareTo(Term that) {
String q1 = this.query;
String q2 = that.query;
return q1.compareTo(q2);
}
public long getWeight() {
return this.weight;
}
public String toString() {
return this.weight + "\t" + this.query;
}
}
BinarySearchDeluxe
import java.lang.*;
import java.util.*;
import java.util.Comparator;
public class BinarySearchDeluxe {
public static <Key> int firstIndexOf(Key[] a, Key key, Comparator<Key> comparator) {
if (a == null || key == null || comparator == null) {
throw new java.lang.NullPointerException();
}
if (a.length == 0) {
return -1;
}
int left = 0;
int right = a.length - 1;
while (left + 1 < right) {
int middle = left + (right - left)/2;
if (comparator.compare(key, a[middle]) <= 0) {
right = middle;
} else {
left = middle;
}
}
if (comparator.compare(key, a[left]) == 0) {
return left;
}
if (comparator.compare(key, a[right]) == 0) {
return right;
}
return -1;
}
public static <Key> int lastIndexOf(Key[] a, Key key, Comparator<Key> comparator) {
if (a == null || key == null || comparator == null) {
throw new java.lang.NullPointerException();
}
if (a == null || a.length == 0) {
return -1;
}
int left = 0;
int right = a.length - 1;
while (left + 1 < right) {
int middle = left + (right - left)/2;
if (comparator.compare(key, a[middle]) < 0) {
right = middle;
} else {
left = middle;
}
}
if (comparator.compare(key, a[right]) == 0) {
return right;
}
if (comparator.compare(key, a[left]) == 0) {
return left;
}
return -1;
}
}
AutoComplete
import java.util.Arrays;
import java.util.Scanner;
import java.io.File;
import java.io.IOException;
import java.util.Comparator;
public class Autocomplete {
public Term[] terms;
public Autocomplete(Term[] terms) {
if (terms == null) {
throw new java.lang.NullPointerException();
}
this.terms = terms.clone();
Arrays.sort(this.terms);
}
public Term[] allMatches(String prefix) {
if (prefix == null) {
throw new java.lang.NullPointerException();
}
Term theTerm = new Term(prefix, 0);
int start = BinarySearchDeluxe.firstIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int end = BinarySearchDeluxe.lastIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int count = start;
System.out.println("Start: " + start + " End: " + end);
if (start == -1 || end == -1) {
// System.out.println("PREFIX: " + prefix);
throw new java.lang.NullPointerException();
} // Needed?
Term[] matches = new Term[end - start + 1];
//matches = Arrays.copyOfRange(terms, start, end);
for (int i = 0; i < end - start; i++) {
matches[i] = this.terms[count];
count++;
}
Arrays.sort(matches, Term.byReverseWeightOrder());
System.out.println("Finished allmatches");
return matches;
}
public int numberOfMatches(String prefix) {
if (prefix == null) {
throw new java.lang.NullPointerException();
}
Term theTerm = new Term(prefix, 0);
int start = BinarySearchDeluxe.firstIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
int end = BinarySearchDeluxe.lastIndexOf(terms, theTerm, Term.byPrefixOrder(prefix.length()));
System.out.println("Finished numberMatches");
return end - start + 1; // +1 needed?
}
public static void main(String[] args) throws IOException {
// Read the terms from the file
Scanner in = new Scanner(new File("wiktionary.txt"));
int N = in.nextInt(); // Number of terms in file
Term[] terms = new Term[N];
for (int i = 0; i < N; i++) {
long weight = in.nextLong(); // read the next weight
String query = in.nextLine(); // read the next query
terms[i] = new Term(query.replaceFirst("\t",""), weight); // construct the term
}
Scanner ip = new Scanner(System.in);
// TO DO: Data Validation Here
int k;
do {
System.out.println("Enter how many matching terms do you want to see:");
k = ip.nextInt();
} while (k < 1 || k > N);
Autocomplete autocomplete = new Autocomplete(terms);
// TO DO: Keep asking the user to enter the prefix and show results till user quits
boolean cont = true;
do {
// Read in queries from standard input and print out the top k matching terms
System.out.println("Enter the term you are searching for. Enter * to exit");
String prefix = ip.next();
if (prefix.equals("*")) {
cont = false;
break;
}
Term[] results = autocomplete.allMatches(prefix);
System.out.println(results.length);
for(int i = 0; i < Math.min(k,results.length); i++)
System.out.println(results[i].toString());
} while(cont);
System.out.println("Done!");
}
}
I apologize for the sloppy code, I have been pulling my hair out for awhile now and keep forgetting to clean it up.
Two examples:
Example 1:
int k = 2;
String prefix = "auto";
Enter how many matching terms do you want to see:
2
Enter the term you are searching for. Enter * to exit
auto
619695 automobile
424997 automatic
Example 2:
int k = 5;
String prefix = "the";
Enter how many matching terms do you want to see:
5
Enter the term you are searching for. Enter * to exit
the
5627187200 the
334039800 they
282026500 their
250991700 them
196120000 there
The purpose of this project is:
Create a class called IntegerSet that implements Comparable interface to be used in simple set applications. Each object of class IntegerSet can hold positive integers in the range 0 through 255 and most common set operations are available. A set must be represented internally as an int array of ones and zeros (or a boolean array). Array element a[ i ] is 1 if integer i is in the set and array element a[ j ] is 0 if integer j is not in the set.
and then add some member method to modify it.
I am not familiar with "implements Comparable interface," but here is what I got so far. The driver cannot test it, it shows "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 256"
Can someone help me find out what the problem is? thanks!
import java.util.Arrays;
public class IntegerSet implements Comparable
{
private int L = 256;
private int[] a = new int[L];
public IntegerSet()
{
Arrays.fill(a, 0);
}
public IntegerSet(int n)
{
a[n] = 1;
}
public IntegerSet(int[] n)
{
a = n;
}
public IntegerSet union(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 || other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet intersection(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i]==1 && other.a[i] ==1)
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet difference(IntegerSet other)
{
int[] c = new int[L];
for(int i = 0; i < L; i++)
{
if(this.a[i] != other.a[i])
c[i] = 1;
else
c[i] = 0;
}
IntegerSet temp = new IntegerSet(c);
return temp;
}
public IntegerSet insertElement(int k)
{
a[k] = 1;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public IntegerSet removeElement(int k)
{
a[k] = 0;
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean isElement(int k)
{
return(a[k] == 1);
}
public String toString()
{
String str = "";
for(int i = 0; i < L; i++)
{
if(a[i] == 1)
str += (i + ", ");
}
return "{" + str + "}";
}
public IntegerSet copy()
{
IntegerSet temp = new IntegerSet(a);
return temp;
}
public boolean subset(IntegerSet other)
{
boolean sub = true;
int i = 0;
while(sub)
{
if(this.a[i] == 1)
{
if(other.a[i] == 1)
sub = true;
else
sub = false;
}
i++;
}
return sub;
}
public boolean superset(IntegerSet other)
{
boolean sup = true;
int i = 0;
while(sup)
{
if(other.a[i] == 1)
{
if(this.a[i] == 1)
sup = true;
else
sup = false;
}
i++;
}
return sup;
}
public void addAll()
{
Arrays.fill(a, 1);
}
public void removeAll()
{
Arrays.fill(a, 0);
}
public int compareTo(Object other)
{
// TODO Auto-generated method stub
return 0;
}
}
and the driver:
public class IntegerSetDriver
{
public static void main(String[] args)
{
IntegerSet s1, s2, s3, s4, s5;
s1 = new IntegerSet(); // s1 is an empty set, {}
s2 = new IntegerSet(5); // s2 is a set with one element, {5}
s1.insertElement(1); // s1 is now {1}
s3 = s1.copy(); // s3 is now {1}
s4 = s1.union(s2); // s4 is now {1, 5} and s1 is still {1}
s5 = s4.insertElement(8).removeElement(5); // s4 is now {1, 8} // s5 references s4
int result = s3.compareTo(s4); // result is -1 (or < 0)
boolean yes = s3.subset(s4); // yes should be true
s5.removeAll(); // s4 and s5 both reference same empty set, {}
s1.removeElement(500); // invalid element so ignore, s1 is still {1}
}
}
You should check your bounds before adding/removing from your int[] a (i.e. 500 is not a valid index).
Also, look at your constructor IntegerSet(input[] n), you cannot just directly "assign" it like that. You need to parse the array and update your local a[] properly.
"n" ranges from 0-255 for values, whereas "a" should only be {1,0}.
A few other things need fixing too.
I came across a post showing how to arrange char array by alphabet order.
seeing this can be done, I want to output the alphabetical order of each character of the input string, in order of the characters of the input string.
I'm a bit stuck. I can get the string reordered alphabetically, but I don't know what to do next.
example is 'monkey' to '354216'
because 'ekmnoy' e is alphabetically first from the set of given characters so e = 1 , k is the second alpha char when sorted so k = 2, and so on.
if you cannot understand I can provide more example to make things clear out.
Code
String str = "airport";
Character[] chars = new Character[str.length()];
for (int z = 0; z < chars.length; z++) {
chars[z] = str.charAt(z);
}
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
StringBuilder sb = new StringBuilder(chars.length);
for (char c : chars) {
sb.append(c);
}
str = sb.toString();
System.out.println(sb);
Output
aioprrt
expected output
Orange -> aegnOr
561432 - 123456
Monkey -> ekMnoy
354216 -> 123456
I dont know what you want to do with double characters, but if you add this few lines to your code at the end you are getting the right result. Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String.
String originalStr = "airport";
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replace(str.charAt(i), String.valueOf(i+1).charAt(0));
}
System.out.println(originalStr);
Output: 1254357
If you want to get the output: 1254367 use replaceFirst:
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
Input:Orange
Output:561432
Input:Monkey
Output:354216
The whole code:
String str = "airport";
String originalStr = str; //creat a backup of str because you change it in your code
Character[] chars = str.toCharArray();
Arrays.sort(chars, new Comparator<Character>() {
public int compare(Character c1, Character c2) {
int cmp = Character.compare(
Character.toLowerCase(c1.charValue()),
Character.toLowerCase(c2.charValue()));
if (cmp != 0) {
return cmp;
}
return Character.compare(c1.charValue(), c2.charValue());
}
});
str = String.valueOf(chars);
System.out.println(str);
//Iterate over the sorted String and replace the charakters in the original String with their indices in the sorted String
for(int i = 0; i<str.length(); i++) {
originalStr = originalStr.replaceFirst(String.valueOf(str.charAt(i)), String.valueOf(i+1));
}
System.out.println(originalStr);
Once you have arranged the characters in order (in a different array from the original) then create a third array by walking the original string and choosing the index of each character from te sorted string.
input: edcba
sorted: abcde
index: 01234
Pseudocode...
for( int i = 0; i < input.length(); i++ ) {
index[i] = sorted.indexOf(input[i]);
}
Result should be 43210 with the given input.
Note that strings with more than 10 characters will result in ambiguous output, which can be handled by inserting spaces in the output. Example:
abcdefghijk ->
012345678910
You can use this below code:
package Test;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
public class Arrange {
public static void main(String[] args) {
String str = "money";
List<Test> strs=new LinkedList<Test>();
List<Test> final_result=new LinkedList<Test>();
for(int i=0;i<str.length();i++)
{
Test t=new Test(i, ""+str.charAt(i), 0);
strs.add(t);
}
Collections.sort(strs,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getS().compareToIgnoreCase(o2.getS()));
}
});
Integer i=1;
for (Test st : strs) {
st.setJ(i);
final_result.add(st);
i++;
}
Collections.sort(final_result,new Comparator<Test>() {
#Override
public int compare(Test o1, Test o2) {
return (o1.getI().compareTo(o2.getI()));
}
});
for (Test test : final_result) {
System.out.println(test.getJ());
}
}
}
class Test{
private Integer i;
private String s;
private Integer j;
public Test() {
// TODO Auto-generated constructor stub
}
public Test(Integer i, String s, Integer j) {
super();
this.i = i;
this.s = s;
this.j = j;
}
public Integer getI() {
return i;
}
public void setI(Integer i) {
this.i = i;
}
public String getS() {
return s;
}
public void setS(String s) {
this.s = s;
}
public Integer getJ() {
return j;
}
public void setJ(Integer j) {
this.j = j;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((i == null) ? 0 : i.hashCode());
result = prime * result + ((j == null) ? 0 : j.hashCode());
result = prime * result + ((s == null) ? 0 : s.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Test other = (Test) obj;
if (i == null) {
if (other.i != null)
return false;
} else if (!i.equals(other.i))
return false;
if (j == null) {
if (other.j != null)
return false;
} else if (!j.equals(other.j))
return false;
if (s == null) {
if (other.s != null)
return false;
} else if (!s.equals(other.s))
return false;
return true;
}
}
I have this code for a heap tree and I'm stuck with the iterators.
I need in-order, pre-order and post-order iterators, but I have no idea how to do it.
If someone has an idea or example please help.
class Numbers implements Comparable<Numbers> {
private int value;
public Numbers(int value) {
this.value = value;
}
public String toString() {
return Integer.toString(value);
}
public int getValue() {
return this.value;
}
public int compareTo(Numbers o) {
int tmp = o.getValue();
if (value > tmp)
return 1;
if (value < tmp)
return -1;
return 0;
}
}
class BinaryHeapIsFull extends Exception {
BinaryHeapIsFull() {
super("There is no more place in the heap!");
}
}
public class BinaryHeap<E extends Comparable> {
E[] elements;
int count;
public BinaryHeap(int maxSize) {
elements = (E[]) new Comparable[maxSize];
this.count = 0;
}
public void enqueue(E elem) throws BinaryHeapIsFull {
if (count == elements.length)
throw new BinaryHeapIsFull();
int i = count++;
while (i > 0 && elements[(i - 1) / 2].compareTo(elem) == 1) {
elements[i] = elements[(i - 1) / 2];
i = (i - 1) / 2;
}
elements[i] = elem;
}
public E findMin() {
return elements[0];
}
public E dequeueMin() {
if (count == 0)
return null;
E result = elements[0];
E last = elements[--count];
int i = 0;
while (2 * i + 1 <= count) {
int child = 2 * i + 1;
if (child < count
&& elements[child + 1].compareTo(elements[child]) == -1)
child++;
if (last.compareTo(elements[child]) == -1
|| last.compareTo(elements[child]) == 0)
break;
elements[i] = elements[child];
i = child;
}
elements[i] = last;
return result;
}
public String toString() {
String print = "";
for (int i = 0; i < count; i++)
print += elements[i].toString() + " ";
return print;
}
public void sort() {
int a = count;
for (int i = 0; i < a; i++) {
System.out.print(findMin() + " ");
dequeueMin();
}
}
public static void main(String[] args) throws BinaryHeapIsFull {
BinaryHeap<Numbers> b = new BinaryHeap<Numbers>(10);
b.enqueue(new Numbers(6));
System.out.println(b.toString());
b.enqueue(new Numbers(3));
System.out.println(b.toString());
b.enqueue(new Numbers(4));
System.out.println(b.toString());
b.enqueue(new Numbers(1));
System.out.println(b.toString());
b.enqueue(new Numbers(5));
System.out.println(b.toString());
b.enqueue(new Numbers(0));
System.out.println(b.toString());
b.enqueue(new Numbers(2));
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
b.dequeueMin();
System.out.println(b.toString());
System.out.println(b.findMin());
b.sort();
}
}
I'd start with three classes, one for each case, that implements the Iterator interface. Give those iterators an instance of your binary heap and let them do their thing.
public class BinaryHeapPreOrderIterator implements Iterator {
// constructor and methods for Iterator here.
}