====== Algorithms ======
A small section about some algorithms I collected and wrote.
===== Sorting =====
==== Heap Sort ====
package ch.ethz.da.vorlesung;
/**
* Heap sort according to lecture.
*
* @author Moritz Hoffmann
*
*/
public class Heapsort {
private final int[] data;
public Heapsort(int[] data) {
this.data = data;
}
public void sort() {
final int length = data.length;
for (int i = length / 2; i >= 0; i--) {
reorder(i, length);
}
for (int i = data.length - 1; i > 0;) {
int z = data[0];
data[0] = data[i];
data[i] = z;
reorder(0, --i);
}
}
private void reorder(int i, int length) {
int j = i << 1;
while (true) {
j = i << 1;
if (j >= length) {
return;
}
if (data[j + 1] > data[j]) {
j++;
}
if (data[i] < data[j]) {
int z = data[i];
data[i] = data[j];
data[j] = z;
i = j;
} else
return;
}
}
}
==== Mergesort ====
This implementation is rather ugly, however, it seems to work.
package ch.ethz.da.serie3;
/**
* Sample implementation of 2 way natural merge sort..
*
* @author Moritz Hoffmann
*
*/
public class Mergesort {
private int sLength = 0;
private int[] source;
private int sStart = -1;
private int[] target;
/**
* Construct new sorter instance.
*
* @param v
* The values to sort. Call {@link Mergesort#sort()} to start
* sorting.
*/
public Mergesort(int[] v) {
source = v;
target = new int[source.length];
}
public int[] getValues() {
return source;
}
/**
* Sort the array the object was created with.
*/
public void sort() {
resetRun();
boolean swap = true;
while (sStart + sLength + 1 < source.length) {
nextRun();
if (sStart > source.length || sLength == source.length - 1) {
swap = false;
break;
}
int s = sStart;
int l = sLength;
nextRun();
if (sStart < source.length) {
System.out.println("Merging " + s + ":" + l + " with " + sStart
+ ":" + sLength);
merge(s, l);
// System.out.println(Arrays.toString(target));
} else {
System.arraycopy(source, s, target, s, l + 1);
resetRun();
int[] t = target;
target = source;
source = t;
}
}
if (swap) {
int[] t = target;
target = source;
source = t;
}
}
/**
* Merge the sequence sStart + sLength with the sequence described by the
* arguments/
*
* @param s
* The sequence's start.
* @param l
* The sequence's length.
*/
private void merge(int s, int l) {
// pointer to current target
int pv = s;
// pointer to the position in the first run
int pa = s;
// pointer to the position in the second run.
int pb = sStart;
// end of new run.
int ev = s + l + sLength + 2;
// end of first run.
int ea = s + l + 1;
// end of second run
int eb = sStart + sLength + 1;
// merge part
while (pa < ea && pb < eb) {
int da = source[pa];
int db = source[pb];
if (da <= db) {
target[pv] = da;
pa = pa + 1;
} else {
target[pv] = db;
pb = pb + 1;
}
pv = pv + 1;
}
// copy part
if (pv < ev) {
if (pa < ea) {
// first part is longer.
System.arraycopy(source, pa, target, pv, ea - pa);
} else {
// second part must be longer.
System.arraycopy(source, pb, target, pv, eb - pb);
}
}
}
/**
* Get the length of the next sorted sequence. Result is stored in sStart
* and sLength.
*/
private void nextRun() {
int i = sStart + sLength + 1;
sStart = i;
final int length = source.length - 1;
while (i < length && source[i] <= source[i + 1]) {
i++;
}
sLength = i - sStart;
}
/**
* Reset sStart and sLength to their initial values after reaching the end
* of the array.
*/
private void resetRun() {
sLength = 0;
sStart = -1;
}
}