I am creating a mergesort method in Java, but I can't seem to know what's wrong. I have tried .add and .set, but it doesn't seem to work. From what I can see in the debugger, the numbers are correct. Please help me!
mergesort(list, 0, list.size() - 1);
private void mergesort(ArrayList<Integer> list, int l, int h) {
if (l < h) {
int m = (l + h) / 2;
mergesort(list, l, m);
mergesort(list, m + 1, h);
merge(list, l, m, h);
}
}
Here is my merge method.
private void merge(ArrayList<Integer> list, int low, int middle, int high) {
ArrayList<Integer> temp = new ArrayList<Integer>();
int low_end = (middle - 1);
int tmp_pos = low;
int num_elements = (high - low + 1);
while ((low <= low_end) && (middle <= high)) {
if (list.get(low) <= list.get(middle)) {
temp.add(tmp_pos++, list.get(low++));
}
else {
temp.add(tmp_pos++, list.get(middle++));
}
}
while (low <= low_end) {
temp.add(tmp_pos++, list.get(low++));
}
while (middle <= high) {
temp.add(tmp_pos++, list.get(middle++));
}
for (int i = 0; i < num_elements; i++) {
list.set(high, temp.get(high));
high--;
}
}
Any help appreciated.
Related
I'm trying to make a program where I count the amount of comparisons quicksort makes but its not 100% accurate. how would I make this comparison counter accurate?
The quicksort takes in an array of n random integers.
Code I have so far:
public int QuickSort(int[] list, int from, int to) {
int icount = 0;
if (from >= to) {
return icount;
}
int p = from;
int i = from;
int j = to;
while (i <= j) {
if (list[i] <= list[p]) {
i++;
icount++;
} else if (list[j] >= list[p]) {
j--;
icount++;
} else {
swap(list, i, j);
i++;
j--;
icount++;
}
}
if (p < j) { // place the pivot in its correct position
swap(list, j, p);
p = j;
icount++;
} else if (p > i) {
swap(list, i, p);
p = i;
icount++;
}
icount += QuickSort(list, from, p - 1);
icount += QuickSort(list, p + 1, to);
return icount;
}
Is there anything wrong with the current code? or is it not possible to be completely accurate with random integers?
I am working on a homework task where I am supposed to make a function that will do a binary insertion sort, but my function does not seem to work properly.
Here I have tried to combine a binary search function with a insertion sort function (it is specified in the homework task that it needs to be in the form of a function: insertionSort(int[] array, int lo, int hi))
public static void insertionSort(int[] array, int lo, int hi){
int mid;
int pos;
for (int i = 1; i < array.length; i++) {
int x= array[i];
while (lo < hi) {
mid = lo + (hi -lo)/2;
if (x == array[mid]) {
pos = mid;
}
if (x > array[mid]) {
lo = mid+1;
}
else if (x < array[mid]) {
hi = mid-1;
}
}
pos = lo;
for (int j = i; j > pos; j--) {
array[j] = array[j-1];
}
array[pos] = x;
}
}
If I try to run it with the list {2,5,1,8,3}, the output will be
2 5 1 3 1 (if lo < hi and if lo > hi)
2 5 3 8 5 (if lo==hi)
What I am expecting though, is a sorted list...
Any idea of what I am doing wrong?
Just to give you a possible idea:
public static void insertionSort(int[] array) {
if (array.length <= 1) {
return;
}
// Start with an initially sorted part.
int loSorted = array.length - 1;
//int hiSorted = array.length;
while (loSorted > 0) {
// Take one from the array
int x = array[0];
// Where in the sorted part to insert?
int insertI = insertPosition(array, loSorted);
// Insert x at insertI
...
--loSorted;
}
}
whenever I need binary search, my function looks the following way:
public static void binarySearch(int arr[], int first, int last, int key){
int mid = (first + last)/2;
while( first <= last ){
if ( arr[mid] < key ){
first = mid + 1;
}else if ( arr[mid] == key ){
System.out.println("Element is found at index: " + mid);
break;
}else{
last = mid - 1;
}
mid = (first + last)/2;
}
if ( first > last ){
System.out.println("Element is not found!");
}
}
In your main method the call looks like:
public static void main(String[] args) {
int arr[] = {10,20,30,40,50};
int key = 30;
int last=arr.length-1;
binarySearch(arr,0,last,key);
}
I hope I was able to help you!
Thank you for your input. I changed the function a little bit, and it seems to be working now
` public static void insertionSort(int[] array, int lo, int hi){
int mid;
int pos;
for (int i = 1; i < array.length; i++) {
int j = i -1;
int x = array[i];
while (lo <= hi) {
mid = lo + (hi -lo)/2;
if (x == array[mid]) {
pos = mid;
break;
}
if (x > array[mid]) {
lo = mid+1;
}
else if (x < array[mid]) {
hi = mid-1;
}
}
while (j >= 0 && array[j] > x) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = x;
}
}
the problem seemed to lay in the last part, where I was trying to move the elements into their right positions. The function is probably not perfect tho, so constructive criticism is welcome :)
What's wrong with my 3-way partition quicksort? When input data less then 100000 it work normal time. When input data = 100000 it work around 9 sec.
I use Dijkstra 3-way partition. If input data consists of a large number of identical elements everything work normal, when input data random work too slow.
static void randomizedQuickSort(int[] a, int l, int r) {
if (l >= r) {
return;
}
int[] m = Partition3(a, l, r);
randomizedQuickSort(a, l, m[0] - 1);
randomizedQuickSort(a, m[1] + 1, r);
}
private static int[] Partition3(int[] nums, int l, int r) {
Random random = new Random();
int k = random.nextInt(r - l + 1) + l;
int mid = nums[k];
int m1 = 0;
int i = 0;
int m2 = r;
while (m1 <= m2) {
if (nums[m1] < mid) {
swap(nums, i, m1);
i++;
m1++;
} else if (nums[m1] > mid) {
swap(nums, m1, m2);
m2--;
} else {
m1++;
}
}
return new int[]{i, m2};
}
You are doing something wrong as the number of swaps is O(n^2) If you count the number of calls to swap you get something like (the first number is the number of elements)
10000: Took 0.078000 seconds, and 33432534 swaps
20000: Took 0.291000 seconds, and 166934755 swaps
40000: Took 1.102000 seconds, and 702291723 swaps
80000: Took 4.482000 seconds, and 2837543629 swaps
160000: Took 17.590000 seconds, and 11373050608 swaps
The problem is the lines
int m1 = 0;
int i = 0;
where you sort from the start of the array on every sort.
int m1 = l; // sort from the start of the section.
int i = l;
The full version is....
public static void main(String[] args) {
for (int t = 100_000; t <= 100_000_000; t *= 10) {
int[] nums = new int[t];
for (int i = 0; i < nums.length; i++) {
nums[i] = random.nextInt();
}
long start = System.currentTimeMillis();
swaps = 0;
randomizedQuickSort(nums, 0, nums.length - 1);
long time = System.currentTimeMillis() - start;
for (int i=0;i<nums.length-1;i++)
if (nums[0] > nums[1])
throw new AssertionError();
System.out.printf("%d: Took %f seconds, and %d swaps%n", t, time / 1e3, swaps);
}
}
static void randomizedQuickSort(int[] a, int l, int r) {
if (l >= r) {
return;
}
long m = Partition3(a, l, r);
int m0 = (int) (m >> 32);
int m1 = (int) m;
randomizedQuickSort(a, l, m0 - 1);
randomizedQuickSort(a, m1 + 1, r);
}
static final Random random = new Random();
static long swaps = 0;
private static long Partition3(int[] nums, int l, int r) {
int k = random.nextInt(r - l + 1) + l;
int mid = nums[k];
int m1 = l;
int i = l;
int m2 = r;
while (m1 <= m2) {
if (nums[m1] < mid) {
swap(nums, i, m1);
i++;
m1++;
} else if (nums[m1] > mid) {
swap(nums, m1, m2);
m2--;
} else {
m1++;
}
}
return ((long) i << 32) | m2;
}
private static void swap(int[] nums, int i, int j) {
int t = nums[i];
nums[i] = nums[j];
nums[j] = t;
swaps++;
}
prints
100000: Took 0.018000 seconds, and 2032183 swaps
1000000: Took 0.168000 seconds, and 24872604 swaps
10000000: Took 1.709000 seconds, and 287681791 swaps
100000000: Took 19.015000 seconds, and 3353327832 swaps
I am a beginner programmer. This is my implementation of the MergeSort algorithm in Java.
I can't seem to fix the bug.
The array gets shuffled but isn't getting sorted. Can someone point out my fault?
public static int[] divide(int a[], int n, int low, int high) {
if (low == high) {
int[] b = { a[low] };
return b;
}
int mid = (low + high) / 2;
divide(a, n / 2, low, mid);
divide(a, n / 2, mid + 1, high);
return conquer(a, low, mid, high);
}
public static int[] conquer(int a[], int low, int mid, int high) {
int p = low;
int q = mid + 1;
int[] sorted = new int[high - low + 1];
int current = 0;
while (p <= mid && q <= high) {
if (a[p] < a[q]) {
sorted[current++] = a[p++];
} else
sorted[current++] = a[q++];
}
if (p <= mid) {
while (p <= mid) {
sorted[current++] = a[p++];
}
}
if (q <= high) {
while (q <= high) {
sorted[current++] = a[q++];
}
}
return sorted;
}
The main issue is that you call divide and not using the returned value (sorted sub-array).
Since you're not using the mid-results, when you call conquer it's not really "conquering".
It can be fixed as follows:
public static int[] divide(int a[], int low, int high) {
if (low == high) {
int[] b = { a[low] };
return b;
}
int mid = (low + high) / 2;
int[] lower = divide(a, low, mid);
int[] higher = divide(a, mid + 1, high);
return conquer(lower, higher);
}
public static int[] conquer(int[] low, int[] high) {
int p = 0;
int q = 0;
int[] sorted = new int[high.length + low.length];
int current = 0;
while (p < low.length && q < high.length) {
if (low[p] <= high[q]) {
sorted[current++] = low[p++];
} else
sorted[current++] = high[q++];
}
while (p <= low.length-1) {
sorted[current++] = low[p++];
}
while (q <= high.length-1) {
sorted[current++] = high[q++];
}
return sorted;
}
Using the code:
int[] a = {3,1,2};
a = divide(a, 0, 2);
System.out.println(Arrays.toString(a));
print:
[1, 2, 3]
I was asked to sort and search an array. The sorting the array was simple and my code worked but then whenever I try to call the binary search method it works for the first element in the array but gives me "-1" as a result
My full code is as follows:
public static void main(String[] args) {
int[] array = new int[5];
array[0] = 50;
array[1] = 40;
array[2] = 10;
array[3] = 20;
array[4] = 100;
sort(array, (array.length - 1));
for (int x = 0; x < array.length; x++) {
System.out.println(" " + array[x]);
}
System.out.println("");
System.out.println("Binary search (R): " + rBsearch(array, 0, (array.length), 20));
}
public static void sort(int[] a, int last) {
if (last > 0) {
int max = findMax(a, last);
swap(a, last, max);
sort(a, last - 1);
}
}
public static int rBsearch(int[] L, int low, int high, int k) {
int mid = (low + high) / 2;
if (low > high) {
return -1;
} else if (L[mid] == k) {
return mid;
} else if (L[mid] < k) {
return rBsearch(L, k, mid + 1, high);
} else {
return rBsearch(L, k, low, mid - 1);
}
}
public static int findMax(int[] arr, int last) {
int max = 0;
for (int i = 0; i <= last; i++) {
if (arr[i] > arr[max]) {
max = i;
}
}
return max;
}
public static void swap(int[] arr, int last, int max) {
int temp = arr[last];
arr[last] = arr[max];
arr[max] = temp;
}
You goofed up the binary search intervals
public static int rBsearch(int[] L, int low, int high, int k) {
int mid = (low + high) / 2;
if (low > high) {
return -1;
} else if (L[mid] == k) {
return L[mid];
} else if (L[mid] < k) {
return rBsearch(L, mid + 1, high, k);
} else {
return rBsearch(L, low, mid - 1, k);
}
}
You did a mistake in calling the rBsearch method in the following lines
Instead of
else if (L[mid] < k) {
return rBsearch(L, k, mid + 1, high);
} else {
return rBsearch(L, k, low, mid - 1);
}
You should use
else if (L[mid] < k) {
return rBsearch(L, mid + 1, high,k); //the order of the parameters
} else {
return rBsearch(L, low, mid - 1,k);
}
Easiest way is:
Convert you array to list: Arrays.asList(array)
For sort: Collections#sort
For search: Collections#binarySearch
See this
Take Array From User
Sort Array using Build-in Function of Java...
then Search Element using Binary Search....
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Scanner;
class BinarySearch
{
public static void main(String args[])
{
int array[];
Scanner input = new Scanner(System.in);
System.out.println("Enter number of elements:");
int Size_Of_Array = input.nextInt();
array = new int[Size_Of_Array];
System.out.println("Enter " + Size_Of_Array + " integers");
for (int counter = 0; counter < Size_Of_Array; counter++)
array[counter] = input.nextInt();
Arrays.sort(array);
System.out.println("Sorting Array is :-");
for (int counter = 0; counter < Size_Of_Array; counter++)
System.out.println(array[counter]);
System.out.println("Enter the search value:");
int Searching_item = input.nextInt();
int First_Index=0;
int Last_Index=Size_Of_Array-1;
int Middle_Index=(First_Index+Last_Index)/2;
while(First_Index <= Last_Index)
{
if(array[Middle_Index] < Searching_item)
{
First_Index=Middle_Index+1;
}
else if ( array[Middle_Index] == Searching_item )
{
System.out.println(Searching_item + " found at location " + (Middle_Index + 1) + ".");
break;
}
else
{
Last_Index = Middle_Index - 1;
}
Middle_Index = (First_Index + Last_Index)/2;
if ( First_Index > Last_Index )
{
System.out.println(Searching_item + " is not found.\n");
}
}
}
}
Result of BinarySearch