My merge sort doesn't seem to be working correctly. When I display the sorted list, it is not sorted and elements are added, where there is supposed to be 9 there is 49.
Anyone see where Im going wrong?
public static <E extends Comparable<E>> void mergeSort(List<E> A) {
int n = A.size();
if (n > 1) {
int half = n / 2;
List<E> B = copyPartialArray(A, 0, half);
List<E> C = copyPartialArray(A, half, n);
mergeSort(B);
mergeSort(C);
merge(B, C, A);
}
}
public static <E extends Comparable<E>> void merge(List<E> B, List<E> C, List<E> A) {
int n1 = B.size();
int n2 = C.size();
int i = 0;
int j = 0;
int k = 0;
while (i < n1 && j < n2) {
if (B.get(i).compareTo(C.get(j)) < 0) {
A.add(k, B.get(i));
i++;
}
else {
A.add(k, C.get(j));
j++;
}
k++;
}
if (i == n1)
for (int p = j; p < n2; p++) {
A.add(k, C.get(p)); k++;
}
else if (j == n2)
for (int p = i; p < n1; p++) {
A.add(k, B.get(p)); k++;
}
}
private static <E extends Comparable<E>> List<E> copyPartialArray(List<E> A, int first, int last) {
int n = last - first;
List<E> copy = new ArrayList<E>(n);
for (int i = 0; i < n; i++)
copy.add(i, A.get(first + i));
return copy;
}
This answer will try to make you realise what's wrong.
It's clear that mergeSort won't do anything to a one element array, but what happens if there are two (for instance [2,1])? You mention there are more elements than before in the result list (list A). Why? What's merge doing to that list? Hint.
Related
class BubbleSort<T> extends ArraySort<T>
{
public void iSort(T[] inArray) {
int n = inArray.length;
int k;
for (int m = n; m >= 0; m--) {
for (int i = 0; i < n - 1; i++) {
k = i + 1;
if (compare(inArray[i], inArray[k])) {
T temp;
temp = inArray[i];
inArray[i] = inArray[k];
inArray[k] = temp;
}
}
}
print(inArray);
}
public static <T extends Comparable<T>> boolean compare(T a, T b) {
if (a.compareTo(b) > 0) {
return true;
} return false;
}
I'm getting (T extends comparable < T >, T extends comparable < T >) in the type bubblesort< T > is not applicable for the arguments (T,T) error!
The quick fix is telling me to change method compare(T,T)< T > to compare(T,T), but that wouldn't resolve my problem. It works perfectly fine when I enter in actual value of elements, for example, compare(3, 5) or compare("hi", "hello") instead of compare(inArray[i], inArray[k]).
I would appreciate it a lot if someone could explain why it's doing that and give me a solution.
You've already defined your class with a generic type T, so there's no point in declaring a separate one for the method:
class BubbleSort<T extends Comparable<T>> extends ArraySort<T> {
public void iSort(T[] inArray) {
int n = inArray.length;
int k;
for (int m = n; m >= 0; m--) {
for (int i = 0; i < n - 1; i++) {
k = i + 1;
if (compare(inArray[i], inArray[k])) {
T temp;
temp = inArray[i];
inArray[i] = inArray[k];
inArray[k] = temp;
}
}
}
print(inArray);
}
public static boolean compare(T a, T b) {
if (a.compareTo(b) > 0) {
return true;
}
return false;
}
}
Anyway, you should denote T extends Comparable<T> in the class declaration rather than in the method.
As I learn Algorithms Book authoried by Robert Sedgewick,when I complete the Selection.java code , I find that there is no output,I hardly know why.
Below is my code.
import java.util.Comparator;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class Selection {
public static void sort(Comparable[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i + 1; j < n; j++)
if (less(a[j], a[min]))
min = j;
exch(a, i, min);
}
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static boolean less(Comparator comparator, Object v, Object w) {
return comparator.compare(v, w) < 0;
}
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
/***************************************************************************
* Check if array is sorted - useful for debugging.
***************************************************************************/
// is the array a[] sorted?
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Comparable[] a, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i - 1]))
return false;
return true;
}
// is the array a[] sorted?
private static boolean isSorted(Object[] a, Comparator comparator) {
return isSorted(a, comparator, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Object[] a, Comparator comparator, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(comparator, a[i], a[i - 1]))
return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
// Selection.sort(a);
show(a);
}
}
And then is my two test
1.http://algs4.cs.princeton.edu/21elementary/tiny.txt
S O R T E X A M P L E
2.http://algs4.cs.princeton.edu/21elementary/words3.txt
bed bug dad yes zoo
now for tip ilk dim
tag jot sob nob sky
hut men egg few jay
owl joy rap gig wee
was wad fee tap tar
dug jam all bad yet
I expect the increasing order in the output,but there is no output.
And I set the Run Configuration--Commman Tab --Input File as ~/tiny.txt
But when I apply and run,there is no output(I use Eclipse Mars 4)
Then I guess maybe the parameter or type Comparable,Because there is a lot warning of it,but I can't handle it.
Anyone could tell me how to solve the problem:)
edu.princeton.cs.algs4.StdOut internally uses PrintWriter initialized as out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET_NAME), true);. The println methods just write to the stream, but does not flush. You may either do:
StdOut.print() at the end of your writing which intern calls out.flush()
StdOut.print(Object o) method which always calls flush()
Reference: StdOut.java
Here is the code for a selection sort function:
public class Selection
{
public static void sort (Comparable [] a)
{ //Sort [] into increasing order.
int N = a.length;
for (int i = 0; i < N; i++)
{ //Exchange a[i] with the smallest entry in a[i+1...N).
int min = i;
for (int j = i+1; j < N; j++)
if (less (a[j], a[min]) ) min = j;
exch(a, i, min); // assume exch has been implemented already
}
}
}
I was told that to support comparators in sort implementations, all I had to do was use "Object" instead of "Comparable", and to pass "Comparator" to "sort()" and "less()" and to use it in "less)".
Would this be the proper way of making it in the comparator interface? :
public class Selection
{
public static void sort (Object [] a, Comparator c)
{ //Sort [] into increasing order.
int N = a.length;
for (int i = 0; i < N; i++)
{ //Exchange a[i] with the smallest entry in a[i+1...N).
int min = i;
for (int j = i+1; j < N; j++)
if (less (c, a[j], a[min]) ) min = j;
exch(a, i, min);
}
}
}
private static booloean less (Comparator c, Object v, Object w)
{
return c.compare(v, w) < 0;
}
private static void exch (Object [] a, int i, int j)
{
Object swap = a[i]; a[i] = a[j]; a[j] = swap;
}
What you did there is indeed a way of generalizing the algorithm, so that it does not only work on Comparable objects, but on arbitrary objects, by using a Comparator. There are some issues with the code (for example, the fact that raw types are used), but your change could be described as "the smallest modification that is necessary to achieve the desired goal".
So, my computer science teacher has told me to make every method here void, except for copyPartArray. I have no idea how to do this, when I try, the sort simply fails.
public static ArrayList<String> mergeSortHelper(ArrayList<String> a) {
int mid = a.size() / 2 - 1;
if (a.size() <= 1)
return a;
return merge(mergeSortHelper(copyPartArray(a, 0, mid)),
mergeSortHelper(copyPartArray(a, mid + 1, a.size() - 1)));
}
public static void mergeSort(ArrayList<String> a) {
ArrayList<String> x = mergeSortHelper(a);
for (int i = 0; i < a.size(); i++) {
a.set(i, x.get(i));
}
}
public static ArrayList<String> merge(ArrayList<String> a,
ArrayList<String> b) {
ArrayList<String> x = new ArrayList<String>(a.size() + b.size());
int aCount = 0;
int bCount = 0;
for (int i = 0; i < a.size() + b.size(); i++) {
if (aCount > a.size() - 1) {
for (int j = bCount; j < b.size(); j++) {
x.add(b.get(j));
}
break;
}
if (bCount > b.size() - 1) {
for (int j = aCount; j < a.size(); j++) {
x.add(a.get(j));
}
break;
}
if ((a.get(aCount)).compareTo(b.get(bCount)) < 0) {
x.add(a.get(aCount));
aCount++;
} else {
x.add(b.get(bCount));
bCount++;
}
}
return x;
}
public static ArrayList<String> copyPartArray(ArrayList<String> a, int s,
int e) {
ArrayList<String> x = new ArrayList<String>();
for (int i = s; i <= e; i++) {
x.add(a.get(i));
}
return x;
I have tried to change my mergeSort to:
public static void mergeSort(ArrayList<String> a) {
int mid = a.size() / 2 - 1;
if (a.size() <= 1)
return;
mergeSort(copyPartArray(a, 0, mid));
mergeSort(copyPartArray(a, mid + 1, a.size() - 1));
merge(a, copyPartArray(a, 0, mid),
copyPartArray(a, mid + 1, a.size() - 1));
}
and get rid of the mergeSortHelper all together.
Now I have:
public static void mergeSort(ArrayList<String> a, int start, int end) {
int mid = (start + end) / 2;
if (a.size() <= 1)
return;
mergeSort(a, start, mid);
mergeSort(a, mid + 1, end);
how would I incorporate my merge method into this?
copyPartArray is going to make a copy of the array so that's no good, your lecturer wants you to pass the array by reference and then also pass in the start/end (or start/length) integers. Try doing something like this:
public static void mergeSort(ArrayList<String> a, int start, int length) {
// refer to 'the array' as a[start] to a[start + length]
}
a will be passed by reference which means you don't need a return value.
So I would change your methods to take a start and length and get rid of copyPartArray all together, you can do your merging in-place on the one array.
I use this method in my blog post on Quicksort.
public class Structure <E extends Comparable<? super E>>{
private E[] d;
public Structure() { d = getArray(1); }
public void show() { show(0); }
private void show(int p){
if( p < d.length && d[p] != null) {
show(r(p));
show(l(p));
System.out.print(d[p] + " ");
}
}
public void add(E obj) {
int p = getPos(obj);
if(p >= d.length)
resize();
d[p] = obj;
}
public boolean present(E obj){
int p = getPos(obj);
return p < d.length && d[p] != null;
}
private int getPos(E obj){
int p = 0;
while(p < d.length && d[p] != null){
int dir = <*1>;
if(dir < 0)
p = l(p);
else if(dir >0)
p = r(p);
else
return p;
}
return p;
}
private E[] getArray(int size) {
return (E[]) new Comparable[size];
}
private void resize(){
E[] temp = getArray(d.length*2 + 1);
for( int i = 0; i < d.length; i++)
temp[i] = d[i];
d = temp;
}
private int l(int i) { return 2 * i + 1;}
private int r(int i) { return 2 * i + 2;}
}
Take that data structure. What is it? I think it's a binary search tree, but I'm pretty sure it's that or a max heap. I'm largely leaning BST, though.
public void fillCol (int n, Collection<Integer> col){
for(int i = 0; i < n; i++)
col.add (i);
}
What is the big O for that method if col is a linked list? I think it's O (N).
And is col a tree set? I think it's O (N log N).
public void sort (List<Double> data){
int lim = data.size();
for(int i = 0; i < lim; i++){
int m = i;
for(int j = i + 1; j < lim; j++)
if(data.get(j) < data.get(m) )
m = j;
data.set( i, data.set(m, data.get(i)));
}
}
and big o for each type of list. I think it's O (N²) for ArrayList and O (N³) for Linked list.
A class that represents a graph uses an adjacency matrix to represent the connections between verticies. What are the space requirements for a graph that contains N nodes with an average of M connections per node?
I think it's O (N²)
Please help! Confirm if I'm right, or correct me if I'm wrong.
It looks like a (not-necessarily-balanced) binary tree, implemented in a manner similar to how a binary heap is often done - in an array where the children of i are 2i and 2i+1.
Someone should've documented what they were doing better.
I agree with your assessment of fillCol.
That sort callable seems like an unrelated question, and yes it does look O(n^2) with a normal data structure.