Java: How to sort part of a 3d array? - java

I have this array: array[2][7][2].
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 7; j++) {
syso(array[i][j][0] + " ");
}
syso("/n");
}
Currently the above code prints out:
4 1 2 5 9 0 1
2 3 1 9 9 3 1
Is there a way to have these sorted somehow? I don't really care about array[i][j][1], only about array[i][j][0].
I wrote myself a QuickSort function but obviously this random piece of code doesn't work:
for (int i = 0; i < array.length; i++) {
quickSort(array[i][0], 0, array[i].length - 1);
}
EDIT:
Here's my QuickSort function as well:
static int partition(int a[], int l, int r) {
int pivot = a[r];
int k=l-1;
for(int i=l; i <= r; i++) {
if (a[i] <= pivot) {
k++;
int w = a[i];
a[i] = a[k];
a[k] = w;
}
}
return k;
}
static void quickSort(int [] a, int l, int r) {
if (l>=r) {
return ;
}
int k = partition(a, l, r);
quickSort(a, l, k-1);
quickSort(a, k+1, r);
}

int[][] another = int[2][7];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
anotner[i][j] = array[i][j][0];
}
}
for (int[] a : anotner) {
Arrays.sort(a);
}
then print anotner as you do using syso().

Related

How to fix ArrayIndexOutOfBoundsException for a Merge sort method?

So the problem that I am running into is that I am trying to get my merge sort implementation to run, but I keep getting an Exception error that says the Array index is out of bounds. This is a runtime error because I am able to compile the program with no issues and it will run up until it hits my merge sort call. One thing that I tried was changing one of my variables to match the other within the merge method (int k = 0; //line 39). When I did this, the code ran, however, the merge sorted array was not correct. I even tried debugging the code, but couldn't see an issue with it. Below is my code:
public static void merge_sort(int A[], int l, int r){
if(l < r){
int m = (l + r)/2;
merge_sort(A, l, m);
merge_sort(A, m + 1, r);
merge(A, l, m, r);//Line17
}
}
public static void merge(int A[], int l, int m, int r){
int n1 = m - l + 1;
int n2 = r - m;
int L[] = new int [n1];
int R[] = new int [n2];
for(int i = 0; i < n1; i++){
L[i] = A[l + i];
}
for(int j = 0; j < n2; j++){
R[j] = A[m + 1 + j];
}
int i = 0;
int j = 0;
int k = 1; //line39
while(i < n1 && j < n2){
if(L[i] <= R[j]){
A[k] = L[i];
i++;
}
else{
A[k] = R[j];
j++;
}
k++;
}
while(i < n1){
A[k] = L[i];
i++;
k++;
}
while(j < n2){
A[k] = R[j]; //line60
j++;
k++;
}
}
And here is the error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 15
at HW3.merge(HW3.java:60)
at HW3.merge_sort(HW3.java:17)
at HW3.main(HW3.java:160) //this line is where I call the method within the main
I understand that this means that the array is going out of the set size of 15 but I am unsure of how to fix this issue. I have tried looking at similar problems, but I did not see a solution to the issue I was having.
Everything else is fine in your code.
Except for this line
int k = 1; //line39
this should be k = l (The letter 'L' in small caps)
You can refer the following code
public class StackExchange {
public static
void mergeSort(int A[], int l , int r) {
if (l < r) {
int m = (l+r)/2;
mergeSort(A, l , m);
mergeSort(A, m+1, r);
merge(A, l, m, r);
}
}
private static void merge(int[] A, int l, int m, int r) {
int n1 = m - l + 1;
int n2 = r - m;
int L[] = new int[n1];
int R[] = new int[n2];
for (int i = 0 ; i < n1; i++) {
L[i] = A[l+i];
}
for (int j = 0 ; j < n2; j++) {
R[j] = A[m + 1 + j];
}
int i = 0, j = 0 , k = l;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
A[k] = L[i];
i++;
} else {
A[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
A[k] = L[i];
i++;
k++;
}
while (j < n2) {
A[k] = R[j];
j++;
k++;
}
}
public static void main (String...s) {
int array[] = new int[] {12, 21, 32, 36, 14, 10, 11, 5, 55, 16, 31, 7, 57, 89, 78};
mergeSort(array, 0, array.length - 1);
printArray(array);
}
private static void printArray(int array[]) {
for (int i : array) {
System.out.println(i + " -- ");
}
}
}
How are you calling your function ? Make sure that you are using object.sort(arr, 0, A.length-1); in main when you pass the max value of the array index.
here example
// Initial index of merged subarry array
int k = l; //this is L not a 1

Whats wrong with this QuickSort implementation?

I cannot guess what is wrong with my code.
INPUT:10, 7, 8, 9, 1, 5
OUTPUT:5 7 9 8 10 1
public class QuickSort {
public static void quickSort(int arr[], int p, int r) {
if (p < r) {
// System.out.println(p+" "+r);
int q = partition(arr, p, r);
quickSort(arr, p, q - 1);
quickSort(arr, q + 1, r);
}
}
public static int partition(int arr[], int p, int r) {
int pivot = arr[r];
int i = p - 1;
for (int j = p; j < r - 1; j++) {
// System.out.println("j");
if (arr[j] <= pivot) {
i = i + 1;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[r];
arr[r] = temp;
return i + 1;
}
static void printArray(int arr[]) {
int n = arr.length;
for (int i = 0; i < n; ++i)
System.out.print(arr[i] + " ");
System.out.println();
}
}
Please clarity my doubt,where to change code so that it works fine.
You are not iterating to the end of the loop (last element). Hence the partition function will not seperate the elements correctly as smaller to the left of pivot and larger to the right of pivot.
Your for loop
for (int j = p; j < r - 1; j++) {
change to
for (int j = p; j <= r - 1; j++) {
Now it is working fine.
See here Ideone

Creating Bottom-Up MergeSort in Java

I am writing code for a bottom-up mergeSort in Java. Right now, I think there may be an indexing issue with the call to merge, but I am having trouble figuring out exactly what my problem is. Any assistance would be greatly appreciated!
public static int[] merge(int[]a, int lo1, int hi1, int lo2, int hi2) {
int[]b = new int[hi2-lo1+1];
int i = lo1;
int j = lo2;
int k = 0;
while (i <= hi1 && j <= hi2) {
if(a[i] < a[j])
b[k++] = a[i++];
else
b[k++]=a[j++];
}
while (i <= hi1)
b[k++] = a[i++];
while (j <= hi2)
b[k++] = a[j++];
for (int l = 0; l < k; l++)
a[lo1 + l] = b[l];
return a; //added
}
public static int[] betterMergeSort(int[]a, int lo, int hi){
for (int comparesize=1; comparesize < (hi-lo+1); comparesize*=2) {
for (int k=lo; k < hi; k+=2*comparesize) {
int[]holder = new int[Math.min(k+2*comparesize-1,hi)-lo+1];
holder = merge(a, k, k+comparesize-1, k+comparesize, Math.min(k+2*comparesize-1, hi));
if (holder.length == (hi-lo+1)){
for (int j=0; j<(hi-lo+1); j++)
a[lo+j] = holder[j];
}
}
}
return a;
}
Note that I need this code to return int[] for now in order to check its accuracy.

Merge Sort Example

I am new to Java and I have tried writing a Merge Sort Program .
MergeSort.java program is below :-
public class MergeSort {
public static int b[] = {6,2,3,1,9};
public void MergeSort(int a[],int left[], int right[]) {
int i = 0,j = 0,k = 0;
int l = left.length;
int r = right.length;
int v = a.length;
while ( i < l && j < r) {
if( left[i] < right[j]) {
a[k] = left[i] ;
i++;
} else {
a[k] = right [j];
j++;
}
k++;
}
while ( i < l ) {
a[k] = left[i];
k++;
i++;
}
while ( j < r ) {
a[k] = right[j];
k++;
j++;
}
}
public void Merge(int a[], int length) {
int n = length;
if(n < 2) return;
int mid = n/2;
int left[] = new int[mid];
int right[] = new int[n-mid];
for (int i = 0 ; i <mid ; i++) {
left[i] = a[i];
}
for (int i = mid ; i <n ; i++) {
right[i-mid] = a[i];
}
Merge(right,n-mid);
Merge(left,mid);
MergeSort(b, left, right);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MergeSort ms = new MergeSort();
ms.Merge(b,b.length);
for(int i=0 ; i < b.length ; i++)
System.out.println(b[i]);
}
}
When I run this program , the output I get is
3
1
6
2
9
But , the expected output is 1 2 3 6 9
Can anyone please help me point out the mistake I am doing and try to help me fix it please .I have tried debugging it on Eclipse but could not spot the bug .
Thanks
Are you sure you meant this in function Merge:
MergeSort(b, left, right);
It seems it should be:
MergeSort(a, left, right);

Where are comparisons in java sorting methods?

Question: Where are comparisons being made in each separate sorting method?
Also if you know please tell me which method count numbers are wrong and where to place my counters instead.trying to understand where and how many times sorting methods make comparisons.
Method A B
Selection 4950 4950
Bubble 99 9900
Insertion 99 5049
Merge 712 1028
Shell 413 649
Quick 543 1041
Okay so to explain some parts, basically Array A is an array from 1-100 in ascending order. So this should be the minimum number of comparisons.
Array B is 100-1 in descending order. So I believe it should be the maximum number of comparisons. Array C is just randomly generated numbers, so it changes every time.
I feel like my selection and bubble sorts were counted correctly. Feel free to let me know where comparisons are being made that I haven't counted, or if I'm counting wrong comparisons.
Side note: Made some global variable to count the methods that were recursive in multiple sections.
class Sorting
{
static int[] X = new int[100];
static int mergecount = 0;
static int quickcount = 0;
public static void selectionSort(int list[])
{
int count = 0;
int position = 0, n = list.length;
for(int j = 0; j < n-1; j++)
{
position = j;
for(int k = j+1; k < n; k++)
{
count++;
if(list[k] < list[position])
position = k;
}
Swap(list, j, position);
}
System.out.println("counter" + count);
}
public static void Swap(int list[], int j, int k)
{
int temp = list[j];
list[j] = list[k];
list[k] = temp;
}
public static void bubbleSort(int list[])
{
int count = 0;
boolean changed = false;
do
{
changed = false;
for(int j = 0; j < list.length - 1; j++)
{
count++;
if(list[j] > list[j + 1])
{
Swap(list, j, j+1);
changed = true;
}
}
} while(changed);
System.out.println("counter" + count);
}
public static void insertionSort(int list[])
{
int count = 0;
for(int p = 1; p < list.length; p++)
{
int temp = list[p];
int j = p;
count++;
for( ; j > 0 && temp < list[j - 1]; j = j-1)
{
list[j] = list[j - 1];
count++;
}
list[j] = temp;
}
System.out.println("counter" + count);
}
public static void mergeSort(int list[])
{
mergeSort(list, 0, list.length - 1);
System.out.println("counter" + mergecount);
}
public static void mergeSort(int list[], int first, int last)
{
if(first < last)
{
int mid = (first + last) / 2;
mergeSort(list, first, mid);
mergeSort(list, mid + 1, last);
Merge(list, first, mid, last);
}
}
public static void Merge(int list[], int first, int mid, int last)
{
int count = 0;
int first1 = first, last1 = mid;
int first2 = mid + 1, last2 = last;
int temp[] = new int[list.length];
int index = first1;
while(first1 <= last1 && first2 <= last2)
{
if(list[first1] < list[first2])
{
temp[index] = list[first1++];
mergecount++;
}
else
temp[index] = list[first2++];
index++;
mergecount++;
}
while(first1 <= last1)
temp[index++] = list[first1++];
while(first2 <= last2)
temp[index++] = list[first2++];
for(index = first; index <= last; index++)
list[index] = temp[index];
}
public static void shellSort(int list[])
{
int count = 0;
int n = list.length;
for(int gap = n / 2; gap > 0; gap = gap == 2 ? 1: (int) (gap/2.2))
for(int i = gap; i < n; i++)
{
int temp = list[i];
int j = i;
count++;
for( ; j >= gap && (temp < (list[j - gap])); j -= gap)
{
list[j] = list[j - gap];
count++;
}
list[j] = temp;
}
System.out.println("counter" + count);
}
public static void quickSort(int start, int finish, int list[])
{
int count = 0;
int left = start, right = finish, pivot, temp;
pivot = list[(start + finish) / 2];
do
{
while(list[left] < pivot)
{
left++;
quickcount++;
}
while(pivot < list[right])
{
right--;
quickcount++;
}
if(left <= right)
{
temp = list[left];
list[left++] = list[right];
list[right--] = temp;
quickcount++;
}
} while(left < right);
if(start < right)
quickSort(start, right, list);
if(left < finish)
quickSort(left, finish, list);
}
public static void copy(int list[])
{
for(int i = 0; i < list.length; i++)
X[i] = list[i];
}
public static void restore(int list[])
{
for(int i = 0; i < list.length; i++)
list[i] = X[i];
}
public static void displayArray(int list[])
{
for(int k = 0; k < list.length; k++)
System.out.print(list[k] + " ");
System.out.println();
}
public static void main(String args[])
{
int[] A = new int[100];
for(int i = 0; i < A.length; i++)
A[i] = i + 1;
int[] B = new int[100];
int q = 100;
for(int i = 0; i < B.length; i++)
B[i] = q--;
int[] C = new int[100];
for(int i = 0; i < C.length; i++)
C[i] = (int)(Math.random() * 100 + 1);
displayArray(A);
copy(A);
selectionSort(A);
displayArray(A);
restore(A);
}
Note that QuickSort performance is greatly influenced by your choice of the pivot. With both of your test arrays sorted (ascending / descending) and because you are picking pivot as array[length/2] you are actually always picking the best pivot. So your test case B won't generate maximum number of comparisons for quicksort. If you were picking array[0] as pivot you'd get maximum number of comparisons for test case A and B.
The easiest way to count comparisons is to use a compare function and do it in there.
static int compareCount = 0;
int compareInt(int a, int b) {
compareCount++;
return a - b; // if 0 they are equal, if negative a is smaller, if positive b is smaller
}
Now just use compareInt in all your algorithms and you'll get an accurate count. You'll have to reset compareCount between each run though.

Categories