My Merge Sort code is not working (Java) - java

I have just written up this code an have been trying for ages to try and find out why it is not printing the sorted list. It is running and there are no bugs, except it just does not print out the sorted list. Can you please help me find whats wrong?
public class Merging {
public static void main(String[] args) {
int[] a = new int[10];
populate(a);
printA(a);
a = merge_sort(a);
printA(a);
}
public static int[] merge_sort(int[] B) {
if (B.length <= 1) {
return B;
}
int midpoint = B.length / 2;
int[] left = new int[midpoint];
int[] right= new int[B.length-midpoint];
int[] result;
for (int i = 0; i < midpoint; i++) {
left[i] = B[i];
}
int x = 0;
for (int j = midpoint; j < B.length; j++) {
if (x < right.length) {
right[x] = B[j];
x++;
}
}
left = merge_sort(left);
right = merge_sort(right);
result = merge(left, right);
return result;
}
public static int[] merge(int[] left, int[] right) {
int lengthResult = left.length + right.length;
int[] result = new int[lengthResult];
int indexL = 0;
int indexR = 0;
int indexRes = 0;
while (indexL < left.length || indexR < right.length) {
if (indexL < left.length && indexR < right.length) {
if (left[indexL] <= right[indexR]) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
} else {
result[indexRes] = right[indexR];
indexR++;
indexRes++;
}
} else if (indexL < left.length) {
result[indexRes] = left[indexL];
indexL++;
indexRes++;
}
}
return result;
}
public static void printA(int[] B) {
for (int i = 0; i < B.length; i++) {
System.out.print(B[i] + " ");
}
}
public static int[] populate(int[] B) {
for (int i = 0; i < B.length; i++) {
B[i] = (int) (Math.random() * 100);
}
return B;
}
}

imagine the case in your loop, where indexL < left.length == false but indexR < right.length == true, you never increase indexR and the loop will never terminate

Related

Java Error code null pointer at different class

The code still error, even though I have already fixed almost half the program
this initialized at main class:
Getting the below error:
Exception in thread "main"
java.lang.NullPointerException
at Tugas7.No3.seqSearch(No3.java:72)
at Tugas7.No3Main.main(No3Main.java:27)
what are you expecting to get out?
I excepting the code when run can search the number
package Tugas7;
public class No3 {
public int[] data;
public int jumData,min,max;
;
public int baris, kolom, posisiBar, posisiKol, posisi;
public void No3(int[] data) {
sort(data, 0, 8);
}
private void merge(int[] data, int left, int middle, int right) {
int[] temp = new int[data.length];
for (int i = left; i <= right; i++) {
temp[i] = data[i];
}
int a = left;
int b = middle + 1;
int c = left;
while (a <= middle && b <= right) {
if (temp[a] <= temp[b]) {
data[c] = temp[a];
a++;
} else {
data[c] = temp[b];
b++;
}
c++;
}
int s = middle - a;
for (int i = 0; i <= s; i++) {
data[c + i] = temp[a + i];
}
}
private void sort(int data[], int left, int right) {
if (left < right) {
int middle = (left + right) / 2;
sort(data, left, middle);
sort(data, middle + 1, right);
merge(data, left, middle, right);
}
}
public void printArray(int arr[]) {
int n = arr.length;
for (int i = 0; i < n; i++) {
System.out.print(arr[i] + " ");
}
System.out.println();
}
public int[] Searching(int[] Data, int jmlData) {
this.jumData = 10;
data = new int[jumData];
for (int i = 0; i < jumData; i++) {
data[i] = Data[i];
}
return data;
}
public int seqSearch(int cari) {
this.posisi = -1;
for (int j = 0; j < 11; j++) {
if (data[j] == cari) {
posisi = j;
break;
}
}
return posisi;
}
public void TampilData() {
for (int i = 0; i < 10; i++) {
System.out.print(data[i] + " ");
}
System.out.println();
}
public void searchMax(int[] data) {
min = data[0];
max = data[0];
for (int i = 0; i < 10; i++) {
if (data[i] < min) {
min = data[i];
} else if (data[i] > max) {
max = data[i];
}
}
}
}

Merge sort algorithm not working

Here is my code for a mergesort in java:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(left, right, input);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}
My issue is that I'm getting an out of bounds exception.
I'm using the debugger and have found that after mergesort(left) and mergesort(right) have finished recursively running.
The arrays left and right, which go into the merge function, have the values [3] and [4] respectively, which is correct.
But when the debugger jumps into the merge function, left has value [3] and right, for some reason is length 2 and has the value [3,4].
This is the source of my out of bounds exception, though I'm not sure why when the merge function runs for its first time, it changes the value of "right".
One problem that is readily visible is that the you shouldn't make 2 arrays of size inputSize/2. Make two arrays of inputSize/2 and inputsize-inputSize/2. Otherwise the algorithm would fail for odd length array.
Also call the function with proper order of the arguments. merge( input, left, right);
I fixed your code and merged them to 1 method, left.length and right.length are limited by input.length so you only need to loop by input.length:
public static void mergeSort(int[] input)
{
if (input.length < 2)
{
return;
}
int[] left = new int[input.length / 2];
int[] right = new int[input.length - input.length / 2];
for (int i = 0; i < input.length; i++)
{
if (i < input.length / 2)
left[i] = input[i];
else
right[i - input.length / 2] = input[i];
}
mergeSort(left);
mergeSort(right);
for (int i = 0, l = 0, r = 0; i < input.length; i++)
{
if (l >= left.length)
{
input[i] = right[r];
r++;
}
else if (r >= right.length)
{
input[i] = left[l];
l++;
}
else
{
if (left[l] >= right[r])
{
input[i] = right[r];
r++;
}
else
{
input[i] = left[l];
l++;
}
}
}
}
you had two problems with your code:
1- as #coderredoc said: your left and right array sizes are wrong:
exemple: if you had an array of 7 elements, your left and right arrays would have a size of 7/2 = 3 so you would have a total of 6 elements in left and right arrays and not 7.
2- you are calling merge function in the mergeSort function with wrong parameters order:
it should be returnArr, left, right and not left,right, returnArr.
Explanation:
if you pass the left array as the first parameter, it would merge the right and the returnArr in the left array. But your left array has a size of 3 and the sum of the sizes of the others is 7 + 3 = 10 that's why you got an OutOfBoundsException.
you need to call merge(input,left,right);
here is the final version:
public class MergeSort {
public static void mergesort(int[] input) {
int inputSize = input.length;
if(inputSize < 2) {
return;
}
int[] left = new int[inputSize/2];
int[] right = new int[inputSize-inputSize/2];
int count = 0;
for(int i=0; i < inputSize/2; i++) {
left[i] = input[i];
}
for(int i=inputSize/2; i<inputSize; i++) {
right[count] = input[i];
count++;
}
mergesort(left);
mergesort(right);
merge(input,left, right);
}
public static int[] merge(int[] returnArr, int[] left, int[] right) {
int leftSize = left.length;
int rightSize = right.length;
int i = 0;
int j =0;
int k = 0;
int count = 0;
while(i < leftSize && j < rightSize) {
if(left[i] <= right[j]) {
returnArr[k] = left[i];
i++;
}
else {
returnArr[k] = right[j];
j++;
}
k++;
}
while(i<leftSize) {
returnArr[k] = left[i];
i++;
k++;
}
while(j < rightSize) {
returnArr[k] = right[j];
j++;
k++;
}
for(int x=0; x<returnArr.length; x++) {
System.out.print(returnArr[x]);
}
return returnArr;
}
public static void main(String[] args) {
int[] array = {3,4,6,2,7,1,8,6};
mergesort(array);
}
}

How to fix NullPointerException in For Loop [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
So I am sort of new to Java and have only been doing it for a couple of months. I'm trying to implement different types of sorting algorithms and I think everything is okay except when I run it I get a NullPointerException on the for loop. I have already read this post What is a NullPointerException, and how do I fix it?. But I still can not figure out how to fix the problem even though I think it is quite simple. Any help?
import java.lang.*;
import java.util.*;
public class SortApp {
public int[] generateRandomArray(int size) {
int[] output = new int[size];
for (int i = 0; i < size; i++) {
output[i] = (int) (Math.random() * Integer.MAX_VALUE);
}
return output;
}
public void printArray(int[] inarray) {
for (int i = 0; i < inarray.length; i++) {
System.out.println(inarray[i]);
}
}
public boolean isSorted(int[] inarray) {
for (int i = 0; i < inarray.length; i++) { //Error here
if (inarray[i] > inarray[i + 1]) {
return false;
}
}
return true;
}
public int[] insertionSort(int[] inarray) {
int[] data = Arrays.copyOf(inarray, inarray.length);
int temp;
int j;
for (int i = 0; i < inarray.length; i++) {
temp = inarray[i];
for (j = 0; (j > 1) && (temp < inarray[j - 1]); j--)
inarray[j] = inarray[j - 1];
inarray[j] = temp;
}
return data;
}
public int[] selectionSort(int[] inarray) {
int[] data = Arrays.copyOf(inarray, inarray.length);
int temp;
int n = inarray.length;
for (int i = 0; i < inarray.length; i++) {
int k = i;
for (int j = i + 1; j < n; j++)
if (inarray[j] < inarray[k])
k = j;
temp = inarray[i];
inarray[i] = inarray[k];
inarray[k] = temp;
}
return data;
}
public int[] mergeSort(int[] inarray, int temp[], int l, int r) {
int[] data = Arrays.copyOf(inarray, inarray.length);
if (l == r) return null;
int mid = (l + r) / 2;
mergeSort(inarray, temp, l, mid);
mergeSort(inarray, temp, mid + 1, r);
int i, j, k;
for (i = l; i <= r; i++)
temp[i] = inarray[i];
for (i = l, j = mid + 1, k = l; i <= mid && j <= r && k <= r; k++)
if (temp[i] < temp[j]) inarray[k] = temp[i];
i++;
inarray[k] = temp[j];
j++;
for (; i <= mid; i++, k++)
inarray[k] = temp[i];
for (; j <= r; j++, k++)
inarray[k] = temp[j];
return data;
}
public static void main(String[] args) {
SortApp myApp = new SortApp();
int[] data = myApp.generateRandomArray(10);
boolean isSortedA = myApp.isSorted(myApp.insertionSort(data));
boolean isSortedB = myApp.isSorted(myApp.selectionSort(data));
boolean isSortedC = myApp.isSorted(myApp.mergeSort(data, data, 0, 0)); //Error here
myApp.printArray(data);
}
}
Error I am getting is this:
Exception in thread "main" java.lang.NullPointerException
at SortApp.isSorted(SortApp.java:23)
at SortApp.main(SortApp.java:91)
It's because of this line:
if (l==r) return null;
You are passing in 0 for both l and r meaning they are equal. Therefore, you are getting a null value passed in to your isSorted() call.

java program to print number in integer as shuffle

Sorry if my question is not clear, lets say I have int a = 1234;.
How can I print as follows, for a number of any length?
123
132
213
231
321
312
Thanks in advance.
public class Test {
private static void swap(int[] p, int i, int j) {
int t= p[i];
p[i]= p[j];
p[j]= t;
return;
}
private static boolean nextPerm(int[] p) { // need p.length > 1
int n= p.length;
int i= n;
if (i-- < 1) return false;
for(;;) {
int ii= i--;
if (p[i] < p[ii]) {
int j= n;
while (!(p[i] < p[--j]));
swap(p, i, j);
for (j= n; j > ii; swap(p, --j, ii++));
return true;
}
if (i == 0) {
for (int j= n; j > i; swap(p, --j, i++));
return false;
}
}
}
public static void main(String[] args) {
int x = 123;
String s = "" + x;
int n = s.length();
int[] p = new int[n];
for (int i = 0; i < n; i++){
p[i] = i;
}
do {
for (int i = 0; i < n; i++){
System.out.print(s.charAt(p[i]));
}
System.out.println();
}
while (nextPerm(p));
}
}
finally I found, below is the code,
class ShuffleNumber {
private static int[] a = {1,2,3};
private static void print(int[] a) {
for (int i = 0; i < a.length; i++)
System.out.print(" " + a[i]);
System.out.println();
}
private static void shuffle(){
int[] b = (int[])a.clone();
for (int i = b.length - 1; i > 0; i--) {
int j = (int)Math.floor(Math.random() * (i+1));
int temp = b[j];
b[j] = b[i];
b[i] = temp;
}
print(b);
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++)
shuffle();
}
}

Get all 1-k tuples in a n-tuple

With n=5 and k=3 the following loop will do it
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
int size=0;
System.out.println();
while (mask > 0) {
if ((mask & 1) == 1) {
System.out.println(".. "+mask);
buffer.append(l.get(j));
if (++size>3){
buffer = new StringBuffer(50);
break;
}
}
System.out.println(" "+mask);
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
but it's not efficient I would like to do it with Banker's sequence and thus explore first singletons, then pairs, then 3-tuple and stop.
I did not find a way do that, but at least this loop should be more efficient:
List<String> l=new ArrayList<String>();
l.add("A");l.add("B");l.add("C");l.add("D");l.add("E");
int broadcastSize = (int) Math.pow(2, l.size());
for (int i = 1; i < broadcastSize; i++) {
StringBuffer buffer = new StringBuffer(50);
int mask = i;
int j = 0;
if (StringUtils.countMatches(Integer.toBinaryString(i), "1") < 4){
while (mask > 0) {
if ((mask & 1) == 1) {
buffer.append(l.get(j));
}
mask >>= 1;
j++;
}
if (buffer.length()>0)
System.out.println(buffer.toString());
}
}
there is also: but k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
//...
// k-tuple
This technique is called Gosper's hack. It only works for n <= 32 because it uses the bits of an int, but you can increase it to 64 if you use a long.
int nextCombo(int x) {
// moves to the next combination with the same number of 1 bits
int u = x & (-x);
int v = u + x;
return v + (((v ^ x) / u) >> 2);
}
...
for (int x = (1 << k) - 1; (x >>> n) == 0; x = nextCombo(x)) {
System.out.println(Integer.toBinaryString(x));
}
For n = 5 and k = 3, this prints
111
1011
1101
1110
10011
10101
10110
11001
11010
11100
exactly as you'd expect.
this should be the most efficient way, even if k embedded loops looks ugly
//singleton
for (int i = 0; i < l.size(); i++) {
System.out.println(l.get(i));
}
//pairs
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
System.out.println(l.get(i)+l.get(j));
}
}
//3-tuple
for (int i = 0; i < l.size(); i++) {
for (int j = i+1; j < l.size(); j++) {
for (int k = j+1; k < l.size(); k++) {
System.out.println(l.get(i)+l.get(j)+l.get(k));
}
}
}
// ...
//k-tuple
Apache commons has iterators for subsets of size k, and for permutations.
Here is an iterator that iterates through 1-k tuples of an n-tuple, that combines the two:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.collections4.iterators.PermutationIterator;
import org.apache.commons.math3.util.Combinations;
public class AllTuplesUpToKIterator implements Iterator<List<Integer>> {
private Iterator<int[]> combinationIterator;
private PermutationIterator<Integer> permutationIterator;
int i;
int k;
int n;
public AllTuplesUpToKIterator(int n, int k) {
this.i = 1;
this.k = k;
this.n = n;
combinationIterator = new Combinations(n, 1).iterator();
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
#Override
public boolean hasNext() {
if (permutationIterator.hasNext()) {
return true;
} else if (combinationIterator.hasNext()) {
return true;
} else if (i<k) {
return true;
} else {
return false;
}
}
#Override
public List<Integer> next() {
if (!permutationIterator.hasNext()) {
if (!combinationIterator.hasNext()) {
i++;
combinationIterator = new Combinations(n, i).iterator();
}
permutationIterator = new PermutationIterator<Integer>(intArrayToIntegerList(combinationIterator.next()));
}
return permutationIterator.next();
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
public static List<Integer> intArrayToIntegerList(int[] arr) {
List<Integer> result = new ArrayList<Integer>();
for (int i=0; i< arr.length; i++) {
result.add(arr[i]);
}
return result;
}
public static void main(String[] args) {
int n = 4;
int k = 2;
for (AllTuplesUpToKIterator iter= new AllTuplesUpToKIterator(n, k); iter.hasNext();) {
System.out.println(iter.next());
}
}
}

Categories