I'm trying to code Quick Sort using recursion but I am getting a stack overflow error. this the second recursive function is giving that continuous error. I'm just unable to figure it out.
public class QuickSortRec {
public static void quicksort(int input[],int a,int b)
{
if(a<b)
{
int pivotpos=partition(input,a,b);
quicksort(input, a,pivotpos-1);
quicksort(input, pivotpos+1,b);
}
}
private static int partition(int input[],int a,int b)
{
int pivot=input[a];
int count=0;
for(int i=a+1;i< input.length;i++)
{
if(input[i]<pivot)
{
count++;
}
}
int temp=input[a];
input[a]=input[count];
input[count]=temp;
for(int i=0;i<count;i++)
{
if(input[i]>pivot)
{
for(int j=input.length-1;j>pivot;j--)
{
if(input[j]<pivot)
{
temp=input[i];
input[i]=input[j];
input[j]=temp;
}
}
}
}
return count;
}
public static void main(String[]args)
{
int arr[]={6,2,10,8,15,3,4};
int a=0;
int b=arr.length-1;
quicksort(arr,a,b);
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
}
}
You have some mistakes. For example you never used b in your pivot function.
You must change your partition function same as below:
public class QuickSortRec {
public static void quicksort(int input[],int a,int b)
{
if(a<b)
{
int pivotpos=partition(input, a,b);
quicksort(input, a,pivotpos-1);
quicksort(input, pivotpos+1,b);
}
}
private static int partition(int arr[],int low,int high)
{
int pivot = arr[high];
int i = (low-1); // index of smaller element
for (int j=low; j<high; j++)
{
// If current element is smaller than or
// equal to pivot
if (arr[j] <= pivot)
{
i++;
// swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
// swap arr[i+1] and arr[high] (or pivot)
int temp = arr[i+1];
arr[i+1] = arr[high];
arr[high] = temp;
return i+1;
}
public static void main(String[]args)
{
int arr[]={6,2,10,8,15,3,4};
int a=0;
int b=arr.length-1;
quicksort(arr,a,b);
for(int i=0;i<arr.length;i++)
{
System.out.print(arr[i]+" ");
}
}
}
I tried to debug your programm, but didnt realy find a solution for the problem so I decided to try to write my own solution because the task seems very interesting to me.
So my goal was to avoid loops completly and only use recursion:
public static void main(String[] args)
{
int array[] = { 6, 2, 10, 8, 15, 3, 4 };
int[] sortedArray = quicksort(array);
for (int currentNumber : sortedArray)
{
System.out.print(currentNumber + " ");
}
}
static int index = 0;
static int tempIndex;
private static int[] quicksort(int[] inputArray)
{
tempIndex = index;
int totalArrayLength = inputArray.length;
if (index != totalArrayLength - 1)
{
if (inputArray[index] > inputArray[index + 1])
{
int temporary = inputArray[index + 1];
inputArray[index + 1] = inputArray[index];
inputArray[index] = temporary;
quickSort2(inputArray);
}
index++;
quicksort(inputArray);
}
return inputArray;
}
private static void quickSort2(int[] inputArray)
{
if (tempIndex != 0 && inputArray[tempIndex] < inputArray[tempIndex - 1])
{
if (tempIndex != 0)
{
int temporary2 = inputArray[tempIndex];
inputArray[tempIndex] = inputArray[tempIndex - 1];
inputArray[tempIndex - 1] = temporary2;
tempIndex--;
quickSort2(inputArray);
}
}
}
Related
I want to build a gui for the merge algorithm using java swing. But I have no idea how I can mix the code that I've made and the new code that I'll add next. I have worked in the past with Fx but I did only some basic stuff. Any tips how I should start on this?
public class MergeSort {
private int[] array;
private int[] tempMergArr;
private int length;
public static void main(String a[]){
// creating the view.
int[] inputArr = {45,23,11,89,77,98,4,28,65,43};
MergeSort mms = new MergeSort();
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++;
}
}
}
thank you in advance.
first time post here.
I am trying to create a class which compares quick sort, merge sort, bubble sort, and selection sort. I have implemented all of the sort methods and created a random array method which populates a random array with 1000 random ints. However when I run my program my main method stops after the initial welcome message and allows for user input. Any help would be greatly appreciated, I'm sure its some simple mistake I am missing.
import java.util.Random;
public class TestSort {
private static int selectCount;
private static int bubbleCount;
private static int mergeCount;
private static int quickCount;
public static void main(String[] args){
System.out.println("Welcome to the search tester. "
+ "We are going to see which algorithm performs the best out of 20 tests");
int testSelection = 0;
int testBubble = 0;
int testQuick = 0;
int testMerge = 0;
//Check tests
int[] a = new int[1000];
populateArray(a);
int[] select = a;
int[] bubble = a;
int[] quick = a;
int[] merge = a;
testSelection = selectionSort(select);
testBubble = bubbleSort(bubble);
testQuick = quickSort(quick,0,0);
testMerge = mergeSort(merge);
System.out.println("Selection sort number of checks: " + testSelection);
System.out.println("Bubble sort number of checks: " + testBubble);
System.out.println("Quick sort number of checks: " + testQuick);
System.out.println("Merge sort number of checks: " + testMerge);
System.out.println("");
}
public static int[] populateArray(int[] a)
{
Random r = new Random();
a = new int[1000];
for(int i=0; i < a.length; i++)
{
int num = r.nextInt(1000);
a[i] = num;
}
return a;
}
//Sorting methods
public static int selectionSort(int[] a)
{
for (int i = 0; i < a.length; i++)
{
int smallestIndex = i;
for (int j=i; j<a.length; j++)
{
if(a[j]<a[smallestIndex])
{
smallestIndex = j;
}
}
if(smallestIndex != i) //Swap
{
int temp = a[i];
a[i] = a[smallestIndex];
a[smallestIndex] = temp;
selectCount++;
}
}
return selectCount;
}
public static int bubbleSort (int[] a)
{
boolean hasSwapped = true;
while (hasSwapped == true)
{
hasSwapped = true;
for(int i = 0; i<a.length-1; i++)
{
if(a[i] > a[i+1]) //Needs to swap
{
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
hasSwapped = true;
bubbleCount++;
}
}
}
return bubbleCount;
}
public static int mergeSort(int [] a)
{
int size = a.length;
if(size<2)//recursive halting point
{
return 0;
}
int mid = size/2;
int leftSize = mid;
int rightSize = size-mid;
int [] left = new int[leftSize];
int [] right = new int[rightSize];
for(int i = 0; i<mid; i++)
{
mergeCount++;
left[i] = a[i];
}
for(int i = mid; i<size; i++)
{
mergeCount++;
right[i-mid]=a[i];
}
mergeSort(left);
mergeSort(right);
//merge
merge(left,right,a);
return mergeCount;
}
private static void merge(int [] left, int [] right, int [] a)
{
int leftSize = left.length;
int rightSize = right.length;
int i = 0;//index of the left array
int j = 0; //index of right array
int k = 0; //index of the sorted array [a]
while(i<leftSize && j<rightSize)
{
if(left[i]<=right[j])
{
a[k] = left[i];
i++;
k++;
}
else
{
a[k] = right[j];
j++;
k++;
}
}
while(i<leftSize)
{
a[k] =left[i];
i++;
k++;
}
while(j<rightSize)
{
a[k] =right[j];
j++;
k++;
}
}
public static int quickSort(int[] a, int left, int right)
{
//partition, where pivot is picked
int index = partition(a,left,right);
if(left<index-1)//Still elements on left to be sorted
quickSort(a,left,index-1);
if(index<right) //Still elements on right to be sorted
quickSort(a,index+1,right);
quickCount++;
return quickCount;
}
private static int partition(int[] a, int left, int right)
{
int i = left;
int j = right; //Left and right are indexes
int pivot = a[(left+right/2)]; //Midpoint, pivot
while(i<j)
{
while(a[i]<pivot)
{
i++;
}
while(a[j]>pivot)
{
j--;
}
if(i<=j) //Swap
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
j--;
}
}
return i;
}
}
Your infinite loop is in bubbleSort:
public static int bubbleSort(int[] a)
{
boolean hasSwapped = true;
while (hasSwapped == true)
{
hasSwapped = false; // Need to set this to false
for (int i = 0; i < a.length - 1; i++)
{
if (a[i] > a[i + 1]) // Needs to swap
{
int temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
hasSwapped = true;
bubbleCount++;
}
}
}
return bubbleCount;
}
The problem is in your bubbleSort() method. The hasSwapped boolean is never set to false, so the while loops infinite times.
There is another problem in your code. In the main method, you will have to assign the array that the populateArray() method returns back to a. And the such assignments as int[] select = a; you do in the main method do not do what you want to do. Instead, just send the array a to your sorting methods.
Like this:
int[] a = new int[1000];
a=populateArray(a);
testSelection = selectionSort(a);
testBubble = bubbleSort(a);
testQuick = quickSort(a,0,0);
testMerge = mergeSort(a);
After many times to try to solve this issue, I can't seem to solve my dilemma. When trying to run my program, the unsorted array will not sort when printing "Sorted Array". Is there something that I'm doing wrong?
public class RecursiveSorter {
private int[] sortedArray;
private int[] array;
public RecursiveSorter() {
array = new int[1];
}
public RecursiveSorter(int[] a) {
array = a;
}
public void setArray(int[] a) {
array = a;
}
public int[] getSortedArray() {
return sortedArray;
}
public int[] getOriginalArray() {
return array;
}
public int[] sort() {
sortedArray = array;
recursiveSort(sortedArray.length - 1);
return sortedArray;
}
public int[] recursiveSort(int endIndex) {
if (endIndex > 0) {
int m = getMaxIndex(endIndex, sortedArray);
swap(m, endIndex, sortedArray);
recursiveSort(endIndex-1);
}
return sortedArray;
}
public int getMaxIndex(int endIndex, int[] a) {
int max = a[0];
int maxIndex = 0;
for (int i = 1; i < endIndex; i++) {
if (a[i] < max) {
max = a[i];
maxIndex = i;
}
}
return maxIndex;
}
//Changed it to make sure that it is swapping the elements correctly
public void swap(int src, int dest, int[] a) {
if(dest <= src)
{
int temp = a[dest];
a[dest] = a[src];
a[src] = temp;
dest++;
src++;
}
}
public String toString() {
return "Original: " + prettyPrint(getOriginalArray()) + "\n" +
"Sorted: " + prettyPrint(getSortedArray());
}
private String prettyPrint(int[] a) {
String s = "";
for (int i : a)
s += i + " ";
return s;
}
public static void main(String[] args) {
// Automate running, but not testing
int[] array = {5, 67, 12, 20};
RecursiveSorter s = new RecursiveSorter(array);
s.sort();
System.out.println(s); // uses Sorter.toString
}
}
You have 3 problems. 2 are in getMaxIndex(): you were not including the last element in the test for the max, and the test for max is not the right. You are computing the min.
public int getMaxIndex(int endIndex, int[] a) {
int max = a[0];
int maxIndex = 0;
for (int i = 1; i <= endIndex; i++) { // use <= instead of <
if (a[i] > max) { // change < in >
max = a[i];
maxIndex = i;
}
}
return maxIndex;
}
And one problem in swap()
public void swap(int src, int dest, int[] a) {
if(src <= dest) // reverse src and dest
{
int temp = a[dest];
a[dest] = a[src];
a[src] = temp;
dest++; // no use, dest is local
src++; // idem
}
}
Then you will have:
Original: 5 12 20 67
Sorted: 5 12 20 67
Actually the orginal array is modified because array and sortedArray reference the same array of int. There is no copy in Java. When you do
public int[] sort() {
sortedArray = array;
recursiveSort(sortedArray.length - 1);
return sortedArray;
}
sortedArray points to the same int[] as array. If you want to keep the orginal one, you need to explicitly do a copy, for instance with System.arrayCopy(...).
I traced the problem down to two points:
first, you have an unnecessary if in swap(...):
public void swap(int src, int dest, int[] a)
{
// if(dest <= src)
// {
int temp = a[dest];
a[dest] = a[src];
a[src] = temp;
// dest++;
// src++;
// }
}
Second, you have a little bug in the for loop of getMaxIndex(...):
public int getMaxIndex(int endIndex, int[] a)
{
int max = a[0];
int maxIndex = 0;
for (int i = 1; i <= endIndex; i++) // substituted < with <=
{
if (a[i] < max)
{
max = a[i];
maxIndex = i;
}
}
return maxIndex;
}
With these changes (and mentionded System.arraycopy), the algorithm should work as intended.
Why you are not sing
// sorting array in #java.util.Arrays;
Arrays.sort(array);
And dont need to recusive call and all
If you need to write your own code, then Choose any sorting algorthim, implement that one by your own.
private static void sort(int[] array){
boolean swapped = true;
int j = 0;
int tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < array.length - j; i++) {
if (array[i] > array[i + 1]) {
tmp = array[i];
array[i] = array[i + 1];
array[i + 1] = tmp;
swapped = true;
}
}
}
}
Here's the code. The output is a very nearly correctly sorted array, but there are several elements out of order. Anyone able to spot the error?
I'm pretty sure the swap and quicksort methods are correct, but I'm posting all the methods here just in case.
package quicksort;
import java.util.Random;
import java.util.Arrays;
public class QuickSort {
/**
* #param args the command line arguments
*/
private static int[] u;
public static void main(String[] args) {
u = makeArray(100);
System.out.println(Arrays.toString(u));
quicksort(0, u.length - 1);
System.out.println(Arrays.toString(u));
}
public static int[] makeArray(int n) {
int[] a = new int[n];
int j;
Random r = new Random();
for (int i = 0; i < n; i++) {
j = (r.nextInt(100) + 1);
a[i] = j;
}
return a;
}
public static int partition(int left, int right, int pivot) {
int p = pivot; // pivot
int lPt = left - 1;
int rPt = right + 1;
while (true) {
while ((lPt < right) && (u[++lPt] < p));
while ((rPt > left) && (u[--rPt] > p));
if (lPt >= rPt) {
break;
} else {
swap(lPt, rPt);
System.out.println("Swapping " + lPt + " " + rPt);
}
}
return lPt;
}
public static void swap (int a, int b) {
int temp = u[a];
u[a] = u[b];
u[b] = temp;
}
public static void quicksort(int l, int r) {
if (r - l <= 0) {
return;
} else {
int part = partition(l, r, u[l]);
quicksort (l, part - 1);
quicksort (part + 1, r);
}
}
}
The problem is in the partition method. The pivot element is not being placed in its correct position at the end of your swaps. I've changed the method signature so that you pass in the position of the pivot element, rather than the value of the pivot, so in quicksort() you would now write:
int part = partition(l, r, l);
In the body of the pivot method, I swapped the pivot element to the end of the section (by swapping with right). So that we then ignore this element with our swaps, I took away the "+ 1" on the initialisation of rPT. I then added a statement after your while loop to move the pivot element into place. With those three changes, the method now looks like this:
public static int partition(int left, int right, int pivotPosition) {
int p = u[pivotPosition]; // pivot
// Move pivot to the end
swap(pivotPosition, right);
int lPt = left - 1;
int rPt = right;
while (true) {
while ((lPt < right) && (u[++lPt] < p));
while ((rPt > left) && (u[--rPt] > p));
if (lPt >= rPt) {
break;
} else {
swap(lPt, rPt);
System.out.println("Swapping " + lPt + " " + rPt);
}
}
// Put pivot in its place
swap(lPt, right);
return lPt;
}
With these changes, the code works for me.
You have to find a values in the left list which is larger than the pivot element and find a value in the right list which is smaller then the pivot element then we exchange the values.
package quicksort;
import java.util.Random;
import java.util.Arrays;
public class QuickSort {
/**
* #param args the command line arguments
*/
private static int[] u;
public static void main(String[] args) {
u = makeArray(10);
System.out.println(Arrays.toString(u));
quicksort(0, u.length - 1);
System.out.println(Arrays.toString(u));
}
public static int[] makeArray(int n) {
int[] a = new int[n];
int j;
Random r = new Random();
for (int i = 0; i < n; i++) {
j = (r.nextInt(100) + 1);
a[i] = j;
}
return a;
}
private static void quicksort(int low, int high) {
int i = low, j = high;
int pivot = u[low];
while (i <= j) {
while (u[i] < pivot) {
i++;
}
while (u[j] > pivot) {
j--;
}
if (i <= j) {
exchange(i, j);
i++;
j--;
}
}
if (low < j) {
quicksort(low, j); // note here
}
if (i < high) {
quicksort(i, high); // note here
}
}
private static void exchange(int i, int j) {
int temp = u[i];
u[i] = u[j];
u[j] = temp;
}
}
So I am trying to make the following code into a recursive method, insertion sort, but for as much as I try I cannot. Can anyone help me?
public static void insertionSort(int[] array){
for (int i = 1; i < array.length; i++){
int j = i;
int B = array[i];
while ((j > 0) && (array[j-1] > B)){
array[j] = array[j-1];
j--;
}
array[j] = B;
}
}
EDIT:
I was thinking of something like this, but it doesn't look very recursive to me...
public static void insertionSort(int[] array, int index){
if(index < array.length){
int j = index;
int B = array[index];
while ((j > 0) && (array[j-1] > B)){
array[j] = array[j-1];
j--;
}
array[j] = B;
insertionSort(array, index + 1);
}
}
Try this:
public class RecursiveInsertionSort {
static int[] arr = {5, 2, 4, 6, 1, 3};
int maxIndex = arr.length;
public static void main(String[] args) {
print(arr);
new RecursiveInsertionSort().sort(arr.length);
}
/*
The sorting function uses 'index' instead of 'copying the array' in each
recursive call to conserve memory and improve efficiency.
*/
private int sort(int maxIndex) {
if (maxIndex <= 1) {
// at this point maxIndex points to the second element in the array.
return maxIndex;
}
maxIndex = sort(maxIndex - 1); // recursive call
// save a copy of the value in variable 'key'.
// This value will be placed in the correct position
// after the while loop below ends.
int key = arr[maxIndex];
int i = maxIndex - 1;
// compare value in 'key' with all the elements in array
// that come before the element key.
while ((i >= 0) && (arr[i] > key)) {
arr[i+1] = arr[i];
i--;
}
arr[i+1] = key;
print(arr);
return maxIndex + 1;
}
// code to print the array on the console.
private static void print(int[] arr) {
System.out.println();
for (int i : arr) {
System.out.print(i + ", ");
}
}
}
public static void insertionSort(int[] array, int index) {
if(array.length == index + 1) return;
insertionSort(array, index + 1);
// insert array[index] into the array
}
You can try this code. It works correctly.
public static int[] InsertionSort(int[] dizi, int n)
{
int i;
if (n < 1) {
InsertionSort(dizi, n - 1);
}
else {
int key = dizi[n];
i = n - 1;
while (i >= 0 && dizi[i] > key) {
dizi[i + 1] = dizi[i];
i = i - 1;
}
dizi[i + 1] = key;
}
return dizi;
}
for the recursion algorithm, we start with the whole array A[1..n], we sort A[1..n-1] and then insert A[n] into the correct position.
public int[] insertionSort(int[] array)
{
//base case
if(array.length==1) return new int[]{ array[0] };
//get array[0..n-1] and sort it
int[] arrayToSort = new int[array.length - 1]{ };
System.arraycopy(array, 0, arrayToSort, 0, array.length -1);
int[] B = insertionSort(arrayToSort);
//now, insert array[n] into its correct position
int[] C = merge(B, array[array.length - 1]);
return C;
}
private int[] merge(int[] array, int n)
{
int[] arrayToReturn = new int[array.length + 1] {};
int j = array.length-1;
while(j>=0 && n <= array[j])
{
arrayToReturn[j+1]=array[j;
j--;
}
arrayToReturn[j] =
}
Try below code by providing ele as an integer array, sortedIndex=index of first element and index=index of second element:
public static void insertionSort(int[] ele, int sortedIndex, int index) {
if (sortedIndex < ele.length) {
if (index < ele.length) {
if (ele[sortedIndex] > ele[index]) {
ele[sortedIndex] += ele[index];
ele[index] = ele[sortedIndex] - ele[index];
ele[sortedIndex] = ele[sortedIndex] - ele[index];
}
insertionSort(ele, sortedIndex, index + 1);
return;
}
if (index == ele.length) {
sortedIndex++;
}
insertionSort(ele, sortedIndex, sortedIndex + 1);
}
}
public static void sort(int[] A, int p, int r) {
if (p < r) {
int q = r - 1;
sort(A, p, q);
combine(A, p, q, r);
}
}
private static void combine(int[] A, int p, int q, int r) {
int i = q - p;
int val = A[r];
while (i >= 0 && val < A[p + i]) {
A[p + i + 1] = A[p + i];
A[p + i] = val;
i--;
}
}
public static void main(String... strings) {
int[] A = { 2, 5, 3, 1, 7 };
sort(A, 0, A.length - 1);
Arrays.stream(A).sequential().forEach(i -> System.out.print(i + ", "));
}
public class test
{
public static void main(String[] args){
test h = new test();
int a[] = { 5, 8, 9, 13, 65, 74, 25, 44, 67, 2, 1 };
h.ins_rec(a, a.length-1);
for(int i=0; i<a.length; i++)
log(a[i]);
}
void ins_rec(int a[], int j){
if( j == 0 ) return;
ins_rec(a, j - 1);
int key = a[ j ];
sort(a, key, j - 1);
}
void sort(int a[], int key, int i){
if( (i < 0) || (a[i] < key) ) {
a[ i + 1 ] = key;
return;
}
a[ i + 1 ] = a[ i ];
sort(a, key, i - 1);
}
private static void log(int aMessage){
System.out.println("\t\t"+aMessage);
}
}