Input: 1,4,2,6,7,5,1,2
Output:2
Counting the number of duplicated numbers in a given array for java. I first sorted the array and then counted duplicates. It's showing me error that variable c is not used and that this method should return value of int.
public class Duplicates
public static void main(String[] args) {
int[]list;
int[]c;
int[] c = new int[list.length];
int temp;
for (int i = 0; i < list.length - 1; i++) {
for (int j = i + 1; j < list; j++) {
if (list[I] > list[j]) {
temp = list[i];
list[i] = list[j];
list[j] = temp;
c = list;
}
}
}
int n = 0;
int counter = 0;
int a = -1;
for (int i = 0; i < c.length; ++i) {
if (c[i] == a) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(c[i]);
} else {
System.out.print("," + c[i]);
}
}
} else {
a = c[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array:" + counter);
}
}
It's showing me error that variable c is not used
This should be a warning. So the code should still run correctly even with this is showing.
this method should return value of int
This is a compilation error and since you are not returning any int array at the end of the method, your method's return type should be void. You should change your method signature as below,
public static void c(int[] list)
Otherwise you will need to return an int array at the end of your method.
After fixing your code,
public class Duplicates {
public static void main(String[] args) {
int[] list = new int[]{1, 4, 2, 6, 7, 5, 1, 2};
int temp;
for (int i = 0; i < list.length; ++i) {
for (int j = 1; j < (list.length - i); ++j) {
if (list[j - 1] > list[j]) {
temp = list[j - 1];
list[j - 1] = list[j];
list[j] = temp;
}
}
}
int n = 0, counter = 0;
int previous = -1;
for (int i = 0; i < list.length; ++i) {
if (list[i] == previous) {
++n;
if (n == 1) {
++counter;
if (counter == 1) {
System.out.print(list[i]);
} else {
System.out.print(", " + list[i]);
}
}
} else {
previous = list[i];
n = 0;
}
}
System.out.println("\nNumber of Duplicated Numbers in array: " + counter);
}
}
I have an assignment where I have to implement heap sort, quick sort, and counting sort into my program. Currently I have no errors but my output is returning as false for my heap and counting sort. What mistakes am I making? How can they be fixed? Please help any feedback will be appreciated.
package sorting;
import java.util.*;
public class Sort2
{
public static int left (int i)
{
return 2 * i + 1;
}
public static int right (int i)
{
return 2 * i + 2;
}
public static int parent (int i)
{
return ((i-1)/2);
}
public static void max_heapify (int[] array, int heap_size, int i)
{
int largest = i;
int l = left(i);
int r = right(i);
if (l < heap_size && array[l] > array[i])
{
largest = l;
}
else
{
largest = i;
}
if (r < heap_size && array[r] > array[largest])
{
largest = r;
}
if (largest != i)
{
int exchange = array[i];
array[i] = array[largest];
array[largest] = exchange;
max_heapify(array, array.length, largest);
}
}
public static int[] build_heap (int[] array)
{
int heap_size = array.length;
for (int i = array.length/2; i >= 1;i--)
{
max_heapify(array, heap_size, i);
}
return array;
}
public static int[] heap_sort (int[] array)
{
build_heap(array);
int heap_size = array.length;
for (int i = array.length;i >= 2;i--)
{
heap_size--;
int exchange = array[0];
array[0] = array[heap_size];
array[heap_size] = exchange;
max_heapify(array, array.length, 1);
}
return array;
}
public static void quick_sort (int[] array, int p, int r)
{
if (p < r)
{
int q = partition(array, p, r);
quick_sort(array, p,q-1);
quick_sort(array, q + 1,r);
}
}
public static int partition (int[] array, int p, int r)
{
int x = array[r];
int i = p - 1;
for (int j = p;j< r;j++)
{
if (array[j] <= x)
{
i++;
int exchange = array[i];
array[i] = array[j];
array[j] = exchange;
}
}
int exchange = array[i+1];
array[i+1] = array[r];
array[r] = exchange;
return i + 1;
}
public static int[] counting_sort (int[] A, int k)
{
int [] C = new int[k+1];
int [] B = new int [A.length];
for(int i = 0;i <= k; i++)
{
C[i] = 0;
}
for(int j = 0; j < A.length; j++)
{
C[A[j]] = C[A[j]] + 1;
}
for (int i = 1; i <= k; i++)
{
C[i] = C[i]+C[i-1];
}
for (int j = A.length - 1;j > 1; j--)
{
B[C[A[j]]- 1]=A[j];
C[A[j]]=C[A[j]] - 1;
}
return B;
}
public static int[] generate_random_array (int n, int k) {
List<Integer> list;
int[] array;
Random rnd;
rnd = new Random(System.currentTimeMillis());
list = new ArrayList<Integer> ();
for (int i = 1; i <= n; i++)
list.add(new Integer(rnd.nextInt(k+1)));
Collections.shuffle(list, rnd);
array = new int[n];
for (int i = 0; i < n; i++)
array[i] = list.get(i).intValue();
return array;
}
public static int[] generate_random_array (int n) {
List<Integer> list;
int[] array;
list = new ArrayList<Integer> ();
for (int i = 1; i <= n; i++)
list.add(new Integer(i));
Collections.shuffle(list, new Random(System.currentTimeMillis()));
array = new int[n];
for (int i = 0; i < n; i++)
array[i] = list.get(i).intValue();
return array;
}
/*
* Input: an integer array
* Output: true if the array is acsendingly sorted, otherwise return false
*/
public static boolean check_sorted (int[] array) {
for (int i = 1; i < array.length; i++) {
if (array[i-1] > array[i])
return false;
}
return true;
}
public static void print_array (int[] array) {
for (int i = 0; i < array.length; i++)
System.out.print(array[i] + ", ");
System.out.println();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
int k = 10000;
System.out.println("Heap sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000) {
int[] array = Sort2.generate_random_array(n);
long t1 = System.currentTimeMillis();
array = Sort2.heap_sort(array);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
boolean flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Heap sort ends ------------------");
//Currently works
System.out.println("Quick sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000)
{
int[] array = Sort2.generate_random_array(n);
long t1 = System.currentTimeMillis();
Sort2.quick_sort(array, 0, n-1);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
boolean flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Quick sort ends ------------------");
int[] array2 = Sort2.generate_random_array(10, 10);
array2 = Sort2.counting_sort(array2,10);
boolean flag = Sort2.check_sorted(array2);
System.out.println(flag);
System.out.println("Counting sort starts ------------------");
for (int n = 100000; n <= 1000000; n=n+100000) {
int[] array = Sort2.generate_random_array(n, k);
long t1 = System.currentTimeMillis();
array = Sort2.counting_sort(array, n);
long t2 = System.currentTimeMillis();
long t = t2 - t1;
flag = Sort2.check_sorted(array);
System.out.println(n + "," + t + "," + flag);
}
System.out.println("Counting sort ends ------------------");
}
}
EDIT I modified your check method to print out the offending array elements:
public static boolean check_sorted( int[] array ) {
for( int i = 1; i < array.length; i++ ) {
if( array[i-1] > array[i] ) {
System.err.println( "Reversed array elements: " + (i-1) + "="
+ array[i-1] + ", " + i + "=" + array[i] );
return false;
}
return true;
}
It looks like the heap sort does not sort the first element of the array:
Heap sort starts ------------------
100000,5,false
Reversed array elements: 0=100000, 1=99999
And ten more like that.
For this homework assignment I would have suggested doing a google search on the specific sorts you were told to complete.
https://www.geeksforgeeks.org/counting-sort/
This will show you the code you just need to modify it for your variables. One thing I noticed right away is you are not building the count array correctly and that is affecting the build of the output array.
https://www.geeksforgeeks.org/heap-sort/
Here is the same instruction and explanation for your heap sort. I did not really look deeply into this as I do not have the time right now. Please use these resources to modify your code and hopefully complete the project.
I have a method which counts how many sums of 3 elements,which are equal to 0, does the array contains. I need help finding the way to stop counting the same triplets in the loop. For instance, 1 + 3 - 4 = 0, but also 3 - 4 +1 = 0.Here is the method:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if(binarySearch(A,sum))
{
count++;
}
}
}
return count;
edit: I have to use the Binary Search (the array is sorted).
Here is the binarySearch code:
private static boolean binarySearch(int A[],int y)
{
y=-y;
int max = A.length-1;
int min = 0;
int mid;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
return true;
}
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
return false;
You can avoid counting different triplets by making one assumption that we need to look for the triplets (x,y,z) with x < y < z and A[x] + A[y] + A[z] == 0.
So what you need to do is to modify the binarySearch function to return the number of index that greater than y and has A[z] == -(A[x] + A[y])
private static int binarySearch(int A[],int y, int index)
{
y=-y;
int max = A.length-1;
int min = index + 1;
int mid;
int start = A.length;
int end = 0;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
start = Math.min(start, mid);
max = mid - 1;
} else
if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
int max = A.length - 1;
int min = index + 1;
while (max>=min)
{
mid = (max+min)/2;
if (y==A[mid])
{
end = Math.max(end, mid);
min= mid + 1;
} else if (y<A[mid])
{
max=mid-1;
}
else
{
min=mid+1;
}
}
if(start <= end)
return end - start + 1;
return 0;
}
So the new function binarySearch will return the total number of index that greater than index and has value equals to y.
So the rest of the job is to count the answer
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
count += binarySearch(A,sum, j);
}
}
return count;
}
Notice how I used two binary search to find the starting and the ending index of all values greater than y!
private static int counter(int A[]) {
int e = A.length;
int count = 0;
for (int i = 0; i < e; i++) {
for (int j = 1; (j < e - 1) && (i != j); j++) {
for (int k = 2; (k < e - 2) && (j != k); k++) {
if (A[i] + A[j] + A[k] == 0) {
count++;
}
}
}
}
return count;
}
private static int counter(int ints[]) {
int count = 0;
for (int i = 0; i < ints.length; i++) {
for (int j = 0; j < ints.length; j++) {
if (i == j) {
// cannot sum with itself.
continue;
}
for (int k = 0; k < ints.length; k++) {
if (k == j) {
// cannot sum with itself.
continue;
}
if ((ints[i] + ints[j] + ints[k]) == 0) {
count++;
}
}
}
}
return count;
}
To solve problem with binary search
Your code was almost correct. all you needed to do was just to replace
if (sum == binarySearch(A,sum)) {
with this
if (binarySearch(A,sum)) {
I am assuming that your binarySearch(A, sum) method will return true if it will found sum in A array else false
private static int counter(int A[]) {
int sum;
int e = A.length;
int count = 0;
for (int i=0; i<e; i++) {
for (int j=i+1; j<e; j++) {
sum=A[i]+A[j];
if (binarySearch(A,sum)) {
count++;
}
}
}
return count;
}
Here is my solution assuming the array is sorted and there are no repeated elements, I used the binary search function you provided. Could the input array contain repeated elements? Could you provide some test cases?
In order to not counting the same triplets in the loop, we should have a way of inspecting repeated elements, the main idea that I used here is to have a list of int[] arrays saving the sorted integers of {A[i],A[j],-sum}.Then in each iteration I compare new A[i] and A[j] to the records in the list, thus eliminating repeated ones.
private static int counter(int A[]){
int sum;
int e = A.length;
int count = 0;
List<int[]> elements = new ArrayList<>();
boolean mark = false;
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
if (-sum == binarySearch(A,sum)){
int[] sort = {A[i],A[j],-sum};
if(-sum == A[i] || -sum == A[j]){
continue;
}else{
Arrays.sort(sort);
//System.out.println("sort" + sort[0] + " " + sort[1]+ " " + sort[2]);
for (int[] element : elements) {
if((element[0] == sort[0] && element[1] == sort[1]) && element[2] == sort[2])
mark = true;
}
if(mark){
mark = false;
continue;
}else{
count++;
elements.add(sort);
//System.out.println("Else sort" + sort[0] + " " + sort[1]);
}
}
}
}
}
return count;
}
you can use a assisted Array,stored the flag that indicate if the element is used;
Here is the code:
private static int counter(int A[])
{
int sum;
int e = A.length;
int count = 0;
// assisted flag array
List<Boolean> flagList = new ArrayList<Boolean>(e);
for (int k = 0; k < e; k++) {
flagList.add(k, false);// initialization
}
for (int i=0; i<e; i++)
{
for (int j=i+1; j<e; j++)
{
sum=A[i]+A[j];
// if element used, no count
if(binarySearch(A,sum)&& !flagList.get(i)&& !flagList.get(j))
{
count++;
flagList.set(i, true);
flagList.set(j, true);
}
}
}
return count;
I am new to Java and have tried to implement mergesort in Java. However, even after running the program several times, instead of the desired sorted output, I am getting the same user given input as the output. I would be thankful if someone could help me understand this unexpected behaviour.
import java.io.*;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) throws IOException {
BufferedReader R = new BufferedReader(new InputStreamReader(System.in));
int arraySize = Integer.parseInt(R.readLine());
int[] inputArray = new int[arraySize];
for (int i = 0; i < arraySize; i++) {
inputArray[i] = Integer.parseInt(R.readLine());
}
mergeSort(inputArray);
for (int j = 0; j < inputArray.length; j++) {
System.out.println(inputArray[j]);
}
}
static void mergeSort(int[] A) {
if (A.length > 1) {
int q = A.length / 2;
int[] leftArray = Arrays.copyOfRange(A, 0, q);
int[] rightArray = Arrays.copyOfRange(A, q + 1, A.length);
mergeSort(leftArray);
mergeSort(rightArray);
A = merge(leftArray, rightArray);
}
}
static int[] merge(int[] l, int[] r) {
int totElem = l.length + r.length;
int[] a = new int[totElem];
int i, li, ri;
i = li = ri = 0;
while (i < totElem) {
if ((li < l.length) && (ri < r.length)) {
if (l[li] < r[ri]) {
a[i] = l[li];
i++;
li++;
} else {
a[i] = r[ri];
i++;
ri++;
}
} else {
if (li >= l.length) {
while (ri < r.length) {
a[i] = r[ri];
i++;
ri++;
}
}
if (ri >= r.length) {
while (li < l.length) {
a[i] = l[li];
li++;
i++;
}
}
}
}
return a;
}
}
Here is a corrected version of your code:
import java.io.*;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) throws IOException{
BufferedReader R = new BufferedReader(new InputStreamReader(System.in));
int arraySize = Integer.parseInt(R.readLine());
int[] inputArray = new int[arraySize];
for (int i = 0; i < arraySize; i++) {
inputArray[i] = Integer.parseInt(R.readLine());
}
mergeSort(inputArray);
for (int j = 0; j < inputArray.length; j++) {
System.out.println(inputArray[j]);
}
}
static void mergeSort(int[] A) {
if (A.length > 1) {
int q = A.length/2;
//changed range of leftArray from 0-to-q to 0-to-(q-1)
int[] leftArray = Arrays.copyOfRange(A, 0, q-1);
//changed range of rightArray from q-to-A.length to q-to-(A.length-1)
int[] rightArray = Arrays.copyOfRange(A,q,A.length-1);
mergeSort(leftArray);
mergeSort(rightArray);
merge(A,leftArray,rightArray);
}
}
static void merge(int[] a, int[] l, int[] r) {
int totElem = l.length + r.length;
//int[] a = new int[totElem];
int i,li,ri;
i = li = ri = 0;
while ( i < totElem) {
if ((li < l.length) && (ri<r.length)) {
if (l[li] < r[ri]) {
a[i] = l[li];
i++;
li++;
}
else {
a[i] = r[ri];
i++;
ri++;
}
}
else {
if (li >= l.length) {
while (ri < r.length) {
a[i] = r[ri];
i++;
ri++;
}
}
if (ri >= r.length) {
while (li < l.length) {
a[i] = l[li];
li++;
i++;
}
}
}
}
//return a;
}
}
When you rebind A in mergeSort():
A = merge(leftArray,rightArray);
this has no effect in inputArray in main().
You need to return the sorted array from mergeSort() similarly to how you return it from merge().
static int[] mergeSort(int[] A) {
...
return A;
}
and in main():
int[] mergedArray = mergeSort(inputArray);
for (int j = 0; j < mergedArray.length; j++) {
System.out.println(mergedArray[j]);
}
The problem is that java is pass by value and not pass by reference... When you are assigning to array A in the merge method you are changing a copy of the reference to A and not the reference to A itself. Therefore you need to pass A into your merge method and make a structural change to A.
The problem lies here:
A = merge(leftArray,rightArray);
Now your merge array does this:
static int[] merge(int[] l, int[] r) {
int[] a = new int[totElem];
// bunch of code
return a;
}
When you started, A was a reference to inputArray. But then you reassigned it to be whatever came out of merge. Unfortunately, that doesn't touch what inputArray is in the main method. That basically says "Oh look at all the work you did... throw it away!"
You could change that with something like
static int[] mergeSort(int[] A) {
// A = merge... // not this
return merge... // use this
}
Then in your main method, you can do
int[] merged = mergeSort(inputArray);
for(int i : merged) System.out.println(i);
public class MergeSort{
public static void sort(int[] in){
if(in.length <2) return; //do not need to sort
int mid = in.length/2;
int left[] = new int[mid];
int right[] = new int[in.length-mid];
for(int i=0; i<mid; i++){ //copy left
left[i] = in[i];
}
for(int i=0; i<in.length-mid; i++){ //copy right
right[i] = in[mid+i];
}
sort(left);
sort(right);
merge(left, right, in);
}
private static void merge(int[] a, int[] b, int[] all){
int i=0, j=0, k=0;
while(i<a.length && j<b.length){ //merge back
if(a[i] < b[j]){
all[k] = a[i];
i++;
}else{
all[k] = b[j];
j++;
}
k++;
}
while(i<a.length){ //left remaining
all[k++] = a[i++];
}
while(j<b.length){ //right remaining
all[k++] = b[j++];
}
}
public static void main(String[] args){
int[] a = {2,3,6,4,9,22,12,1};
sort(a);
for(int j=0; j<a.length; j++){
System.out.print(a[j] + " ");
}
}
}
public void sort(int[] randomNumbersArrray)
{
copy = randomNumbersArrray.clone();
mergeSort(0 , copy.length - 1);
}
private void mergeSort(int low, int high)
{
if(low < high)
{
int mid = ((low + high) / 2);
mergeSort(low, mid); //left side
mergeSort(mid + 1, high); // right side
merge(low, mid, high); //combine them
}
}
private void merge(int low, int mid, int high)
{
int temp[] = new int[high - low + 1];
int left = low;
int right = mid + 1;
int index = 0;
// compare each item for equality
while(left <= mid && right <= high)
{
if(copy[left] < copy[right])
{
temp[index] = copy[left];
left++;
}else
{
temp[index] = copy[right];
right++;
}
index++;
}
// if there is any remaining loop through them
while(left <= mid || right <= high)
{
if( left <= mid)
{
temp[index] = copy[left];
left++;
index++;
}else if(right <= high)
{
temp[index] = copy[right];
right++;
index++;
}
}
// copy back to array
for(int i = 0; i < temp.length; i++)
{
copy[low + i] = temp[i];
}
}
package Sorting;
public class MergeSort {
private int[] original;
private int len;
public MergeSort(int length){
len = length;
original = new int[len];
original[0]=10;
original[1]=9;
original[2]=8;
original[3]=7;
original[4]=6;
original[5]=5;
original[6]=4;
original[7]=3;
original[8]=2;
original[9]=1;
int[] aux = new int[len];
for(int i=0;i<len;++i){
aux[i]=original[i];
}
Sort(aux,0,len);
}
public void Sort(int[] aux,int start, int end){
int mid = start + (end-start)/2;
if(start < end){
Sort(aux, start, mid-1);
Sort(aux, mid, end);
Merge(aux, start, mid, end);
}
}
public void Merge(int[] aux, int start, int mid, int end){// while array passing be careful of shallow and deep copying
for(int i=start; i<=end; ++i)
auxilary[i] = original[i];
int i = start;
int k = start;
int j = mid+1;
while(i < mid && j <end){
if(aux[i] < aux[j]){
original[k++] = aux[i++];
}
else{
original[k++] = aux[j++];
}
}
if(i == mid){
while(j < end){
original[k++] = aux[j++];
}
}
if(j == end){
while(i < mid){
original[k++] = aux[i++];
}
}
}
public void disp(){
for(int i=0;i<len;++i)
System.out.print(original[i]+" ");
}
public static void main(String[] args) {
MergeSort ms = new MergeSort(10);
ms.disp();
}
}
The above codes are a little confused
Never use variables with names: "k", "j", "m",... this makes the code very confusing
Follows the code in an easier way...
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
Integer[] itens = {2,6,4,9,1,3,8,7,0};
Integer[] tmp = new Integer[itens.length];
int left = 0;
int right = itens.length - 1;
mergeSort(itens, tmp, left, right);
System.out.println(Arrays.toString(itens));
}
private static void mergeSort(Integer[] itens, Integer[] tmpArray, int left, int right) {
if(itens == null || itens.length == 0 || left >= right){
return;
}
int midle = (left + right) / 2;
mergeSort(itens, tmpArray, left, midle);
mergeSort(itens, tmpArray, midle + 1, right);
merge(itens, tmpArray, left, midle + 1, right);
}
private static void merge(Integer[] itens, Integer[] tmpArray, int left, int right, int rightEnd) {
int leftEnd = right - 1;
int tmpIndex = left;
while (left <= leftEnd && right <= rightEnd){
if (itens[left] < itens[right] ){
tmpArray[tmpIndex++] = itens[left++];
} else {
tmpArray[tmpIndex++] = itens[right++];
}
}
while (left <= leftEnd) { // Copy rest of LEFT half
tmpArray[tmpIndex++] = itens[left++];
}
while (right <= rightEnd) { // Copy rest of RIGHT half
tmpArray[tmpIndex++] = itens[right++];
}
while(rightEnd >= 0){ // Copy TEMP back
itens[rightEnd] = tmpArray[rightEnd--];
}
}
}
Might as well add my take on this:
Takes two int arrays and merges them.
Where 'result' is an array of size a.length + b.length
public static void merge( int[] a, int[] b, int[] result )
{
int i = 0, j = 0;
while ( true )
{
if ( i == a.length )
{
if ( j == b.length )
return;
result[ i + j ] = b[ j ];
j++;
}
else if ( j == b.length )
{
result[ i + j ] = a[ i ];
i++;
}
else if ( a[ i ] < b[ j ] )
{
result[ i + j ] = a[ i ];
i++;
}
else
{
result[ i + j ] = b[ j ];
j++;
}
}
}
public class MyMergeSort {
private int[] array;
private int[] tempMergArr;
private int length;
public static void main(String a[]){
int[] inputArr = {45,23,11,89,77,98,4,28,65,43};
MyMergeSort mms = new MyMergeSort();
mms.sort(inputArr);
for(int i:inputArr){
System.out.print(i);
System.out.print(" ");
}
}
public void sort(int inputArr[]) {
this.array = inputArr;
this.length = inputArr.length;
this.tempMergArr = new int[length];
doMergeSort(0, length - 1);
}
private void doMergeSort(int lowerIndex, int higherIndex) {
if (lowerIndex < higherIndex) {
int middle = lowerIndex + (higherIndex - lowerIndex) / 2;
// Below step sorts the left side of the array
doMergeSort(lowerIndex, middle);
// Below step sorts the right side of the array
doMergeSort(middle + 1, higherIndex);
// Now merge both sides
mergeParts(lowerIndex, middle, higherIndex);
}
}
private void mergeParts(int lowerIndex, int middle, int higherIndex) {
for (int i = lowerIndex; i <= higherIndex; i++) {
tempMergArr[i] = array[i];
}
int i = lowerIndex;
int j = middle + 1;
int k = lowerIndex;
while (i <= middle && j <= higherIndex) {
if (tempMergArr[i] <= tempMergArr[j]) {
array[k] = tempMergArr[i];
i++;
} else {
array[k] = tempMergArr[j];
j++;
}
k++;
}
while (i <= middle) {
array[k] = tempMergArr[i];
k++;
i++;
}
}
}
very simple and easy to understand
static void sort(char[] data) {
int length = data.length;
if (length < 2)
return;
int mid = length / 2;
char[] left = new char[mid];
char[] right = new char[length - mid];
for(int i=0;i<mid;i++) {
left[i]=data[i];
}
for(int i=0,j=mid;j<length;i++,j++) {
right[i]=data[j];
}
sort(left);
sort(right);
merge(left, right, data);
}
static void merge(char[] left, char[] right, char[] og) {
int i = 0, j = 0, k = 0;
while(i < left.length && j < right.length) {
if (left[i] < right[j]) {
og[k++] = left[i++];
} else {
og[k++] = right[j++];
}
}
while (i < left.length) {
og[k++] = left[i++];
}
while (j < right.length) {
og[k++] = right[j++];
}
}
I have a parallel version of Merge Sort. I am benefiting from the RecursiveAction and ForkJoinPool. Note that the number of workers can be set as a constant. However, I am setting it as the number of available processors on the machine.
import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class ParallelMergeSorter {
private int[] array;
public ParallelMergeSorter(int[] array) {
this.array = array;
}
public int[] sort() {
int numWorkers = Runtime.getRuntime().availableProcessors(); // Get number of available processors
ForkJoinPool pool = new ForkJoinPool(numWorkers);
pool.invoke(new ParallelWorker(0, array.length - 1));
return array;
}
private class ParallelWorker extends RecursiveAction {
private int left, right;
public ParallelWorker(int left, int right) {
this.left = left;
this.right = right;
}
protected void compute() {
if (left < right) {
int mid = (left + right) / 2;
ParallelWorker leftWorker = new ParallelWorker(left, mid);
ParallelWorker rightWorker = new ParallelWorker(mid + 1, right);
invokeAll(leftWorker, rightWorker);
merge(left, mid, right);
}
}
private void merge(int left, int mid, int right) {
int[] leftTempArray = Arrays.copyOfRange(array, left, mid + 1);
int[] rightTempArray = Arrays.copyOfRange(array, mid + 1, right + 1);
int leftTempIndex = 0, rightTempIndex = 0, mergeIndex = left;
while (leftTempIndex < mid - left + 1 || rightTempIndex < right - mid) {
if (leftTempIndex < mid - left + 1 && rightTempIndex < right - mid) {
if (leftTempArray[leftTempIndex] <= rightTempArray[rightTempIndex]) {
array[mergeIndex] = leftTempArray[leftTempIndex];
leftTempIndex++;
} else {
array[mergeIndex] = rightTempArray[rightTempIndex];
rightTempIndex++;
}
} else if (leftTempIndex < mid - left + 1) {
array[mergeIndex] = leftTempArray[leftTempIndex];
leftTempIndex++;
} else if (rightTempIndex < right - mid) {
array[mergeIndex] = rightTempArray[rightTempIndex];
rightTempIndex++;
}
mergeIndex++;
}
}
}
}
public class MergeTwoSortedArray {
public void approach_2(int[] arr1, int[] arr2) {
List<Integer> result = IntStream.concat(Arrays.stream(arr1), Arrays.stream(arr2)).boxed().sorted()
.collect(Collectors.toList());
System.out.println(result);
}
public void approach_3(Integer[] arr1, Integer[] arr2) {
List<Integer> al1 = Arrays.asList(arr1);
List<Integer> al2 = Arrays.asList(arr2);
List<Integer> result = new ArrayList<>();
int i = 0, j = 0;
while (i < al1.size() && j < al2.size()) {
if (al1.get(i) < al2.get(j)) {
result.add(al1.get(i));
i++;
} else {
result.add(al2.get(j));
j++;
}
}
while (i < al1.size()) {
result.add(al1.get(i));
i++;
}
while (j < al2.size()) {
result.add(al2.get(j));
j++;
}
System.out.println(result);
}
public static void main(String[] args) {
MergeTwoSortedArray obj = new MergeTwoSortedArray();
int[] arr1 = { 3, 6, 76, 85, 91 };
int[] arr2 = { 1, 6, 78, 89, 95, 112 };
obj.approach_2(arr1, arr2);
Integer[] arr3 = { 3, 6, 76, 85, 91 };
Integer[] arr4 = { 1, 6, 78, 89, 95, 112 };
obj.approach_3(arr3, arr4);
}
}