MergeSort, Java Code not working? - java

The Merging function:
static int[] merge(int v[], int start, int middle, int end){
int i = start, temp, j = middle, k = 0;
int a[] = new int[end];
while(j < end && i < middle){
if(v[i] > v[j]){
a[k++] = v[j++];
}
else{
a[k++] = v[i++];
}
}
for(temp = i; temp < middle; temp++){
a[k++] = v[temp];
}
for(temp = j; temp < end; temp++){
a[k++] = v[temp];
}
for(i = 0; i < end; i++)
v[i] = a[i];
return v;
}
The Splitting Function:
static int[] split(int v[], int start, int end){
int array[] = new int[end-start+1];
for(int i = start, j = 0; i <= end; i++, j++){
array[j] = v[i];
}
return array;
}
The MergeSort Function:
static int[] mergesort(int v[], int start, int end) {
int middle = v.length/2, left, right;
if(end-start <= 1){
return v;
}
mergesort(split(v, start, middle), start, middle);
mergesort(split(v, middle+1, end-1), middle+1, end-1);
merge(v, start, middle, end);
return v;
}
The Main function:
public static void main(String[] args){
int v[] = {6,1,8,2,9,3};
int end = 6, i;
v = mergesort(v, 0, end);
for(i = 0; i < end; i++){
System.out.print(v[i]+" ");
}
System.out.println();
}
The output given is 2 6 1 8 9 3 and should be 1 2 3 6 8 9
I'm pretty sure it's here:
mergesort(split(v, start, middle), start, middle);
mergesort(split(v, middle+1, end-1), middle+1, end-1);
merge(v, start, middle, end);
these functions return an array but what can i assign it to ?

Here is my solution, which is using lists instead of arrays.
public <E extends Comparable<E>> List<E> mergeSort(List<E> unsortedList) {
if (unsortedList == null || unsortedList.size() < 2) {
return unsortedList;
} else {
List<E> left = new LinkedList<E>();
List<E> right = new LinkedList<E>();
int pivot = (1 + unsortedList.size()) / 2;
while (!unsortedList.isEmpty()) {
if (pivot > 0) {
left.add(unsortedList.remove(0));
pivot--;
} else {
right.add(unsortedList.remove(0));
}
}
left = mergeSort(left);
right = mergeSort(right);
return merge(left, right);
}
}
private <E extends Comparable<E>> List<E> merge(List<E> left, List<E> right) {
List<E> sortedResult = new ArrayList<E>(left.size() + right.size());
while (!left.isEmpty() && !right.isEmpty()) {
E leftElem, rightElem;
leftElem = left.get(0);
rightElem = right.get(0);
if (leftElem.compareTo(rightElem) < 0) {
sortedResult.add(leftElem);
left.remove(0);
} else {
sortedResult.add(rightElem);
right.remove(0);
}
}
sortedResult.addAll(left);
sortedResult.addAll(right);
return sortedResult;
}
INPUT:
[6, 1, 3, 5, 5, 1, 9, 8, 7, 8]
OUTPUT:
[1, 1, 3, 5, 5, 6, 7, 8, 8, 9]

You are complicating a little bit your code. Here is an alternative implementation. Let me know if it works:
class MergeSort2{
public static void main(String[] args){
int[] arrayToMerge = new int[]{45,66,7,8,444,3,5,66,7,1,9,3,55,6,7};
mergeSort(arrayToMerge, 0 , arrayToMerge.length-1);
for(int i=0; i < arrayToMerge.length; i++){
System.out.println(" -> " + arrayToMerge[i]);
}
}
public static void mergeSort(int[] arr, int start, int end){
if(start < end){
int mid = (start + end) /2;
mergeSort(arr,start, mid);
mergeSort(arr, mid + 1, end);
mergeArray(arr, start, mid, end);
}
}
public static void mergeArray(int[] arr, int start, int mid, int end){
int[] temp = new int[end - start + 1];
int i= start, j = mid + 1 , k = 0;
while(i <= mid && j <= end){
if(arr[i] < arr[j]){
temp[k] = arr[i];
k++;
i++;
}
else
{
temp[k] = arr[j];
k++;
j++;
}
}
while(i <= mid){
temp[k] = arr[i];
k++;
i++;
}
while (j <= end){
temp[k] = arr[j];
k++;
j++;
}
i= start;
k=0;
while (k < temp.length && i <= end){
arr[i] = temp[k];
i++;
k++;
}
}
}

Related

Why does my partition algorithm return ArrayIndexOutOfBoundsException

I have been trying to learn algorithms in Java and have been trying to implement Hoares partition and have been looking at multiple examples but when i try to implement in intellij I get this error:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index -1 out of bounds for length 6
at QuickSort.partitionSort(QuickSort.java:18)
at QuickSort.quickSort(QuickSort.java:35)
at QuickSort.main(QuickSort.java:52)
I am not sure how to solve this as I've just started learning
import java.io.*;
public class QuickSort {
static int partitionSort(int[] arr, int h, int l) {
int i = l - 1;
int j = h + 1;
int pivot = arr[l];
while(true) {
do {
i++;
} while(arr[i] < pivot);
do {
j--;
} while(arr[j] > pivot);
if (i >= j)
return j;
int tempArr = arr[i];
arr[i] = arr[j];
arr[j] = tempArr;
}
}
static void quickSort(int[] arr, int l, int h) {
if (l > h)
return;
int q = partitionSort(arr, l, h);
quickSort(arr, l, q);
quickSort(arr, q + 1, h);
}
static void pArray(int[] arr, int n) {
for (int i = 0; i < n; i++) {
System.out.print(" " + arr[i]);
System.out.println();
}
}
public static void main(String args[]) {
int arr[] = {5, 8, 10, 3, 4, 1};
int n = arr.length;
quickSort(arr, 0, n - 1);
System.out.println("Before sorting: " + arr);
System.out.println("Sorted array: ");
pArray(arr, n);
}
}
The index parameters to partitionSort are reversed. Also my version of Java didn't allow System.out.println("Sorted array: " + arr); and this should be done before doing the sort. You might consider using the middle value for pivot in partitionSort.
import java.io.*; // is this needed?
public class QuickSort {
static int partitionSort(int[] arr, int l, int h) { // fix, swap l and h
int i = l - 1;
int j = h + 1;
int pivot = arr[l]; // might want to use int pivot = arr[l + (h-l)/2];
while(true) {
do { // could be while(arr[++i] < pivot);
i++;
} while(arr[i] < pivot);
do { // could be while(arr[--j] > pivot);
j--;
} while(arr[j] > pivot);
if (i >= j)
return j;
int tempArr = arr[i];tempArr
arr[i] = arr[j];
arr[j] = tempArr;
}
}
static void quickSort(int[] arr, int l, int h) {
if (l >= h) // fix, if l >= h, nothing to do
return;
int q = partitionSort(arr, l, h);
quickSort(arr, l, q);
quickSort(arr, q + 1, h);
}
static void pArray(int[] arr, int n) {
for (int i = 0; i < n; i++) {
System.out.print(" " + arr[i]);
System.out.println();
}
}
public static void main(String args[]) {
int arr[] = {5, 8, 10, 3, 4, 1};
int n = arr.length;
System.out.println("Before sorting: "); // changed
pArray(arr, n); // changed
quickSort(arr, 0, n - 1);
System.out.println("Sorted array: ");
pArray(arr, n);
}
}

Rotation of the array means that each element is shifted right by one index, and the last element of the array is also moved to the first place

For example, the rotation of array A = [3, 8, 9, 7, 6] is [6, 3, 8, 9, 7]. The goal is to rotate array A K times;
that is, each element of A will be shifted to the right by K indexes.
For example, given array A = [3, 8, 9, 7, 6] and K = 3, the function should return [9, 7, 6, 3, 8].
I want this in java.
I have tried this.
public static int[] rotation(int[] a,int k) {
int[] newArray = new int[a.length];
for(int i = 0 ; i < a.length ; i++) {
int newPosition = (i + k)%a.length;
newArray[newPosition] = a[i];
}
return newArray;
}
I didnt get what exactly wants topic starter but here my code for this task
class Solution {
public int[] solution(int[] arr, int k) {
int[] newArr = new int[arr.length];
if (arr.length == 0) return arr;
k = k%arr.length;
for (int i=0; i<arr.length; i++) {
newArr[i] = arr[(i + (arr.length - k)) % (arr.length)];
}
return newArr;
}
}
You can also use A = B.clone();
public int[] solution(int[] A, int K) {
// write your code in Java SE 8
int [] B =new int [A.length];
for(int l=0;K>l;K--){
int j=0;
for(int i=0;i<A.length;i++){
if(i==0){
B[j]=A[A.length-1];
j++;
}
else{
B[j]=A[i-1];
j++;
}
}
//below part
/*for(int i= 0;i<A.length;i++){
A[i]=B[i];
}*/
A = B.clone();
}
return B;
}
If you like :D
You can print the result using Arrays.toString. For example:
System.out.println(Arrays.toString(rotation(new int[] { 3, 8, 9, 7, 6}, 3)));
public int[] solution(int[] A, int K) {
// write your code in Java SE 8
int [] B =new int [A.length];
for(int l=0;K>l;K--){
int j=0;
for(int i=0;i<A.length;i++){
if(i==0){
B[j]=A[A.length-1];
j++;
}
else{
B[j]=A[i-1];
j++;
}
}
for(int i= 0;i<A.length;i++){
A[i]=B[i];
}
}
return B;
}
function solution(A, K) {
function shiftArray(arrayToShift, newArray=[] ){
newArray[0] = arrayToShift[arrayToShift.length-1] ;
for (var i=1; i<arrayToShift.length; i++){
newArray[i] = arrayToShift[i-1];
}
// console.log("arrayToShift");
// console.log(newArray);
return newArray;
}
var newArray = A;
for(var i=0; i<K; i++){
newArray = shiftArray(newArray);
}
return newArray
}
console.log(solution([3, 8, 9, 7, 6], 3));
Achieved 100% correctness
public int[] solution(int[] A, int K) {
// write your code in Java SE 8
if(K == A.length || A.length == 0)
return A;
if(K > A.length) {
K = K%A.length;
}
int[] arr1 = Arrays.copyOfRange(A, A.length-K, A.length);
int[] arr2 = Arrays.copyOfRange(A, 0, A.length-K);
int aLen = arr1.length;
int bLen = arr2.length;
int[] result = new int[aLen + bLen];
System.arraycopy(arr1, 0, result, 0, aLen);
System.arraycopy(arr2, 0, result, aLen, bLen);
return result;
}
Here's my solution using JavaScript, tested 100%.
function solution(A, K) {
for(let i=0; i<K; i++) {
let lastIndex = A.length - 1;
let lastItem = A[lastIndex];
for(let j=(A.length-1); j>-1; j--) {
if(j>0) {
A[j] = A[j-1];
} else {
A[j] = lastItem;
}
}
}
return A;
}
class Solution {
public int[] solution(int[] A, int K){
if((A.length == 0) || (K == 0)){
return A;
}
int [] B = new int[A.length];
int c = K;
while(c != 0){
for(int i = 1; i< A.length; i++){
B[i] = A[i-1];
}
c--;
B[0] = A[A.length-1];
System.arraycopy(B, 0, A, 0, A.length);
}
return A;
}
}
In Kotlin:
fun flipList(list: List<Int>, times: Int): List<Int> {
val flippedList = list.toMutableList()
val referenceList = list.toMutableList()
repeat(times) {
var position = 0
referenceList.forEach {
position++
if (position < list.size)
flippedList[position] = referenceList[position -1]
else
flippedList[0] = referenceList.last()
}
referenceList.clear()
referenceList.addAll(flippedList)
}
return flippedList
}
Unit Teste
class FlipListUnitTest {
private val referenceListMock = listOf(1,2,3,4)
private val referenceListOneTimeFlipResultMock = listOf(4,1,2,3)
private val referenceListFourTimesFlipResultMock = listOf(1,2,3,4)
#Test
fun `check test api is working`(){
assertTrue(true)
}
#Test
fun `check list flip 1 time`(){
assertTrue(flipList(referenceListMock, 1) == referenceListOneTimeFlipResultMock)
}
#Test
fun `check list flip 4 time`(){
assertTrue(flipList(referenceListMock, 4) == referenceListFourTimesFlipResultMock)
}
}
Here in my code
public static int[] solution(int[] A, int K){
if(A.length > 0) {
for(int i = 0; i < K ; i++){
int temp = A[A.length - 1];
for(int j = A.length - 2; j >= 0; j--){
A[j + 1] = A[j];
}
A[0] = temp;
}
}
return A;
}
public static int[] solution(int[] A, int K) {
if(A.length<1)
return A;
int[] newArray = new int[A.length];
while (K>0){
newArray[0]=A[A.length-1];
for(int i=0; i<A.length-1; i++){
newArray[i+1]=A[i];
}
for (int i=0; i<newArray.length; i++) {
A[i]=newArray[i];
}
K--;
}
return A;
}
An array A consisting of N integers is given. Rotation of the array means that each element is shifted right by one index, and the last element of the array is moved to the first place.
Hi everyone here is another simple solution for this problem in JAVA, 100% working.
class Solution {
public int[] solution(int[] A, int K) {
// Corner cases to save resources
if(K == 0 || A.length <= 0 || A.length == K){
return A;
}
// Loop to traverse K times
for(int i=0; i<K; i++){
int last = A[A.length - 1]; // Last digit
// Loop to traverse A.Length times in swing order,
// so that first element can be set
for(int j=A.length-1; j>0; j--){
A[j] = A[j-1];
}
// Set last element
A[0] = last;
}
// Return result
return A;
}
}
Here is my answer in JavaScript
function solution(A, K){
let arr = [];
let lastIndex = A.length -1;
let rotation = K-1;
for(let i = 0; i < K; i++){
arr[rotation] = A[lastIndex];
--lastIndex;
--rotation;
}
for(let j = 0; j <= lastIndex; j++){
arr.push(A[j]);
}
return arr;
}
Here is my answer in Python without loop and using string substitution
def solution(A, K):
K = K % len(A) if K > len(A) else K
if (K == 0) or (K == len(A)) or (len(A) in [0, 1]):
return A
first_index = len(A) - K
return A[first_index:] + A[:first_index]
function solution(A, K) {
let tmpA = [];
for (let i = 1; i <= K; i++){
tmpA.unshift(A.pop());
}
for (let i = 1; i <= K; i++){
A.unshift(tmpA.pop());
}
return A;
}
This is the code written in PHP but logic can be used in any language.
function solution($A, $K) {
// write your code in PHP7.0
$cnt = count($A);
for($i=1; $i<=$K; $i++){
foreach($A as $key=>$val){
$key++;
if($key==$cnt){
$A[0] = $val;
}
else
{
$A[$key] = $val;
}
}
}
return $A;
}
javascript | score: 100%
function solution(A, K) {
for(let i=0 ; i<K ; i++){
let lastIndex = A.length-1;
let lastNumber = A[lastIndex];
A.unshift(lastNumber);
A.pop();
}
return A;
}
public static int[] rotateArrayKTimes(int[] A, int K) {
if (A.length == 0 || A.length > 1000 || K > 100) {
return new int[]{};
}
for (int index = 0; index < K; index++) {
int temp = A[A.length - 1];
System.arraycopy(A, 0, A, 1, A.length - 1);
A[0] = temp;
}
return A;
}
JAVA solution -
class Solution2 {
public int[] solution(int[] arr, int k) {
int temp;
int startindex = 0;
if (arr.length != 0) {
for (int i = 1; i <= k; i++) {
temp = arr[arr.length - 1];
for (int j = arr.length - 1; j >= startindex; j--) {
if (j != (startindex)) {
arr[j] = arr[j - 1];
} else
arr[startindex] = temp;
}
}
} else
System.out.println("This is empty array");
return arr;
}
}

What is wrong with my algorithm for counting inversion?

The code is working fine for test cases like {3,3,3,3}, {1,2,3,4}, {2,4,1,3,5} etc. But it isn't working for {1,20,6,4,5,2,7,3,5}, which should return 18 inversions. My code is getting me 16 inversions.
class Test{
static int count =0;
public static void main(String[] agrs) {
int[] arr = new int[] {1,20,6,4,5,2,7,3,5};
sort(arr);
System.out.println("\n"+count);
}
private static void sort(int[] arr) {
int length = arr.length;
int tempArr[] = new int[length];
divideAndConquer(arr,tempArr,0,length-1);
}
private static void divideAndConquer(int[] arr, int[] tempArr, int low, int high) {
if(low < high){
int middle = low + (high - low) / 2;
divideAndConquer(arr, tempArr, low, middle);
divideAndConquer(arr, tempArr, middle + 1, high);
merge(arr, tempArr, low, middle, high);
}
}
private static void merge(int[] arr, int[] tempArr, int low, int middle,int high) {
for (int i = low; i <= high; i++)
tempArr[i] = arr[i];
int i = low, j = middle + 1, k = low;
while (i <= middle && j <= high) {
if(tempArr[i] < tempArr[j]) {
arr[k] = tempArr[i];
i++;
}
else {
arr[k] = tempArr[j];
if(tempArr[i] != tempArr[j])
count += middle+1 - i;
System.out.println(count);
j++;
}
k++;
}
while (i <= middle) {
arr[k] = tempArr[i];
k++;
i++;
}
}
}
Just change the line
if(tempArr[i] < tempArr[j]) {
to
if(tempArr[i] <= tempArr[j]) {
and the problem will be solved.

Java: Reverse sorting methods

So these sorting methods sort numbers in a lesser to greater order, how would I reverse these? I've tried reversing the operations but that doesn't seem to work :/
Still trying to learn Java, thank you for the help
//Selection Sort Method
public static void SelectionSort(int a[], int n) {
int smallest;
for (int i = 0; i < a.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < a.length; index++) {
if (a[index] < a[smallest]) {
swap(a, smallest, index);
}
}
}
}
//Selection Sort swap method to call on
public static void swap(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
//Bubble Sort Method
public static void BubbleSort(int a[], int n) {
int i, j, t = 0;
for (i = 0; i < n; i++) {
for (j = 1; j < (n - i); j++) {
if (a[j - 1] > a[j]) {
t = a[j - 1];
a[j - 1] = a[j];
a[j] = t;
}
}
}
}
//Insertion Sort Method
public static void InsertionSort(int a[], int n) {
int insert;
for (int next = 1; next < a.length; next++) {
insert = a[next];
int moveItem = next;
while (moveItem > 0 && a[moveItem - 1] > insert) {
a[moveItem] = a[moveItem - 1];
moveItem--;
}
a[moveItem] = insert;
}
}
//Quick Sort Method
public static void QuickSort(int a[], int low, int high) {
int partitionLoc;
if (low < high) {
partitionLoc = partition(a, low, high);
QuickSort(a, low, partitionLoc - 1);
QuickSort(a, partitionLoc + 1, high);
}
}
public static int partition(int a2[], int left, int right) {
boolean moveLeft = true;
int separator = a2[left];
while (left < right) {
if (moveLeft == true) {
while ((a2[right] >= separator) && (left < right)) {
right--;
}
a2[left] = a2[right];
moveLeft = false;
} else {
while ((a2[left] <= separator) && (left < right)) {
left++;
}
a2[right] = a2[left];
moveLeft = true;
}
}
a2[left] = separator;
return left;
}
You can leave your method as is and reverse the array:
public static void reverse(int[] a) {
for (int i = 0 ; i < a.length / 2 ; i++) {
int t = a[i];
a[i] = a[a.length - 1 - i];
a[a.length - 1 - i] = t;
}
}
int[] a = // ...
whateverSort(a);
reverse(a);
Just reverse the comparison in each sort:
SelectionSort
a[index] < a[smallest] => a[index] > a[smallest]
BubbleSort
a[j - 1] > a[j] => a[j - 1] < a[j]
InsertionSort
a[moveItem - 1] > insert => a[moveItem - 1] < insert
QuickSort
(a2[right] >= separator) => (a2[right] <= separator)
(a2[left] <= separator) => (a2[left] >= separator)

Mergesort in java

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);
}
}

Categories

Resources