Trying to implement merge sort with some modifications - java

I am trying to implement merge sort algorithm with some optimization like using temp storage only once and avoiding the copy till the last.Everything is okay and many test files are passing except some.The thing that is happening here is with unsorted array,the algorithm is showing some problems.I have written print statements in my code trying to reach the problem,but unable to do so.As many tests are passing,i believe there is nothing major wrong in the program,just it misses something.
I have tried to implement the program and it is successful in many ways,just 3 cases doesn't pass.But,the main problem i am facing is that test case Mergesort_two() doesn't pass because its simple .It's just calling two numbers and asserting in sorted form,but my program is denying it.I believe its a minor error which i am unable to figure out.
public static void mergesort(int[] input, int[] temp,
int start, int end,
boolean intoTemp) {
if (start == end) {
return;
}
if ((start + 1) == end) {
if (intoTemp == true) {
temp[start] = input[start];
return;
}
}
if (start < end) {
if (intoTemp == false) {
intoTemp = true;
int mid = (start + end)/2;
mergesort(input, temp, start, mid, intoTemp);
mergesort(input, temp, mid, end, intoTemp);
merge(input, temp, start, mid, end);
System.out.println("Input Array: " + Arrays.toString(input) +
" Temp: " + Arrays.toString(temp) + " intoTemp: " +
intoTemp + "Start Mid End: " + start + " " + mid + " " + end);
}
else if(intoTemp == true) {
intoTemp = false;
int mid = (start + end)/2;
mergesort(input, temp, start, mid, intoTemp);
mergesort(input, temp, mid, end, intoTemp);
merge(temp, input, start, mid, end);
System.out.println("Input Array: " + Arrays.toString(input) +
" Temp: " + Arrays.toString(temp) + " intoTemp: " +
intoTemp + "Start Mid End: " + start + " " + mid + " " + end);
}
}
if (start == 0 && end == input.length) {
System.arraycopy(temp, 0, input, 0, input.length);
}
}
/** Merges input[start...mid-1] with input[mid...end-1] into
* output[start...end-1]. The input array should not be modified at
* all, and only start...end-1 of the output array should be changed.
*
* #param input Input array
* #param output Output array
* #param start Starting index
* #param mid Midpoint index
* #param end Ending index+1
*/
public static void merge(int[] input, int[] output,
int start, int mid, int end) {
if (input == null || (start == mid && mid == end)) {
return;
}
int i = start;
int j = mid - 1;
int k = mid;
int index = start;
while (i <= j && k < end) {
if (input[i] <= input[k]) {
output[index] = input[i];
i++;
index++;
}
if (input[i] > input[k]) {
output[index] = input[i];
k++;
index++;
}
}
while (i <= j) {
output[index] = input[i];
index++;
i++;
}
while (k < end) {
output[index] = input[k];
index++;
k++;
}
}
}
////// Test Cases
#Test
public void testMergesort_Two() {
System.out.println("mergesort one element");
int[] array = new int[2];
// Already sorted
array[0] = 10; array[1] = 13;
CSSE240_Assign4.mergesort(array);
assertEquals(array[0], 10);
assertEquals(array[1], 13);
// Unsorted
array[0] = 3; array[1] = -4;
CSSE240_Assign4.mergesort(array);
assertEquals(array[0], -4);
assertEquals(array[1], 3);
}
#Test
public void testMergesort_Large() {
System.out.println("mergesort one large");
Random rng = new Random();
for(int s = 3; s < 20; ++s) {
int[] array = new int[s];
int[] orig = new int[s];
// Fill with random values.
for(int i = 0; i < s; ++i) {
array[i] = rng.nextInt();
orig[i] = array[i];
}
CSSE240_Assign4.mergesort(array);
Arrays.sort(orig);
// Make sure both arrays agree
for(int i = 0; i < s; ++i)
assertEquals(orig[i], array[i]);
}
}
#Test
public void testMergeInterleaved() {
// Various cases where the left/right halves are interleaved. We test
// this by picking a modulo m and moving all the elements where
// e % m < m/2 to the right side.
System.out.println("merge reverse sorted");
for(int s = 3; s < 20; ++s) {
int[] array = new int[s];
int mid = 0;
// Move the elements of the array around into the two halves.
for(int m = 2; m < 5; ++m) {
// Populate the array with 0...s-1
for (int i = 0; i < s; ++i) {
array[i] = i;
}
int[] left = new int[s];
int[] right = new int[s];
int lc = 0, rc = 0;
for(int i = 0; i < s; ++i)
if(array[i] % m < m/2)
right[rc++] = array[i];
else
left[lc++] = array[i];
// Copy back into the array
int j = 0;
for(int i = 0; i < lc; ++i)
array[j++] = left[i];
for(int i = 0; i < rc; ++i)
array[j++] = right[i];
mid = lc; // Midpoint
int[] output = new int[s];
Arrays.fill(output, -1);
// TODO: check different endpoints...
CSSE240_Assign4.merge(array, output, 0, mid, s);
for(int i = 0; i < s; ++i)
assertEquals(output[i], i);
}
}
}
testMergesort_Two Failed : expected <-4> but was <3>
testMergeInterleaved Failed: expected <0> but was <1>
testMergeSort_Large Failed : expected:<-1131373963> but was:<-2038582366>

Changes noted in comments.
public static void mergesort(int[] input, int[] temp,
int start, int end,
boolean intoTemp) {
if (start == end) {
return;
}
if ((start + 1) == end) {
if (intoTemp == true) {
temp[start] = input[start];
return;
}
}
if (intoTemp == false) {
intoTemp = true;
int mid = (start + end)/2;
mergesort(input, temp, start, mid, intoTemp);
mergesort(input, temp, mid, end, intoTemp);
merge(temp, input, start, mid, end);
} else {
intoTemp = false;
int mid = (start + end)/2;
mergesort(input, temp, start, mid, intoTemp);
mergesort(input, temp, mid, end, intoTemp);
merge(input, temp, start, mid, end);
}
}
public static void merge(int[] input, int[] output,
int start, int mid, int end) {
int i = start;
int j = mid; // using j instead of k
// and mid instead of j
int index = start;
while (i < mid && j < end) { // using mid
if (input[i] <= input[j]) {
output[index] = input[i];
i++;
index++;
} else { // change
output[index] = input[j]; // was input[i]
j++;
index++;
}
}
while (i < mid) { // using mid
output[index] = input[i];
i++; // changed order for consistency
index++;
}
while (j < end) {
output[index] = input[j];
j++; // changed order for consistency
index++;
}
}

Related

Find the largest index occurrence of a number using binary search

This code, generates a random number, sorts it in ascending order and does the binary search to find a target value. MY QUESTION IS HOW DO I MODIFY THIS CODE TO FIND THE LARGEST INDEX OF THE GIVEN TARGET. For example the array has { 1, 2 , 3, 5, 5, 5, 5}, the target is 5, so the output should be 6 instead of 3. Thankyou.
import java.util.*;
public class Sort
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
System.out.print("How many numbers do you want? ");
int howMany = in.nextInt();
int [] myArray = getSortedRandomArray(howMany);
System.out.print("\nFor what value would you like to search? ");
int target = in.nextInt();
int index = bsearch ( myArray, target);
if (index >= 0)
{
System.out.println("The value " + target + " occurs at index " + index);
}
else
{
System.out.println("The value " + target + " does not occur in the array. ");
}
}
public static int bsearch(int[] arr, int key)
{
int lo = 0, hi = arr.length - 1;
{
while (lo < hi)
{
int mid = (lo + hi) / 2;
if (arr[mid] <= key)
lo = mid + 1;
if (arr[mid] > key)
hi = mid;
}
if (arr[lo] == key) {
return lo;
}
else if ((arr[lo] != key) && (arr[lo-1] == key)){
return lo - 1;
}
else{
System.out.print("The value " + key + " does not occur in the array. ");
}
return -1 ;
}
public static int[] getSortedRandomArray (int howMany)
{
int[] returnMe = new int [howMany];
Random rand = new Random();
for (int i = 0; i < howMany ; i++)
returnMe[i] = rand.nextInt(Integer.MAX_VALUE) + 1;
for (int i = 1; i <= (howMany - 1); i++)
{
for (int j = 0; j <= howMany - i -1; j++)
{
int tmp = 0;
if (returnMe[j] > returnMe[j+1])
{
tmp = returnMe[j];
returnMe[j] = returnMe[j + 1];
returnMe[j + 1] = tmp;
}
}
}
System.out.print("Here is a random sorted array: ");
for ( int i = 0; i < howMany; i++)
System.out.print(returnMe[i] + " ");
return returnMe;
}
You can do this by modifying the binary search algorithms code like this:
public static int bsearch(int[] arr, int key) {
int lo = 0, hi = arr.length - 1;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (arr[mid] <= key)
lo = mid + 1;
if (arr[mid] > key)
hi = mid;
}
if (arr[lo] == key) {
return lo;
}
else {
return lo - 1;
}
}
This code instead searches for the first number larger than key. That can be any number, 6 or 10000, it doesn't matter. As you can see, if arr[mid] is equal to key, the code will still run on the interval [mid, hi]. Why those two returns at the end? Well if input array is like the one you gave, lo will end being the index of the last 5, but if we add another number at the end of input array, lo will be index of the number behind the last 5. Therefore, we have 2 different cases.
Also, you can't do it with a linear loop like other answers, because that reduces the algorithm to O(n) and it ends just being a linear search on a reduced array.
If you update your bsearch algorithm a little you can ask it to seek higher matches recursively. However whether this is more efficient than a linear loop would depend on what the input array looked like.
public static int bsearch(int[] arr, int key, int lo, int hi) {
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (arr[mid] == key) {
System.out.println("The value " + key + " is found at " + mid);
int higherResult = bsearch(arr, key, mid + 1, hi);
if (higherResult < 0) {
return mid;
}
return higherResult;
}
if (arr[mid] < key) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return -1;
}

I'am confused that the random quick sort is slower than normal quick sort

With the Introduction to algorithm .The Professor intro that the random quick sort can decrease the percentage of bad situation and improve the performance of time cost.But I wonder if there any problem with my code that cause the result
in contrast.
Here are my java code
public class quickSort {
public final int size = 200000;
public final int times = 10;
#Test
public void quick_sort() {
int test1[] = new int[size];
int test2[];
int k = 0;
long t1 = 0;
long t2 = 0;
for (int i = 0; i < size; i++) {
test1[i] = i;
}
test2 = test1.clone();
while (k < times) {
shuffle(test1);
shuffle(test2);
long start1 = System.currentTimeMillis();
split1(test1, 0, test1.length -1);
t1 += System.currentTimeMillis() - start1;
long start2 = System.currentTimeMillis();
split2(test2, 0, test2.length -1);
t2 += System.currentTimeMillis() - start2;
k++;
}
System.out.println("normal quick sort time is" + t1 + "ms");
System.out.println("random quick sort time is " + t2 + "ms");
}
public void split1(int[] arr, int start, int end) {
if (start >= end) {
return;
} else {
int middle = sort(arr, start, end);
split1(arr, start, middle - 1);
split1(arr, middle + 1, end);
}
}
public void split2(int[] arr, int start, int end) {
if (start >= end) {
return;
} else {
int middle = random_sort(arr, start, end);
split2(arr, start, middle - 1);
split2(arr, middle + 1, end);
}
}
// random quick sort
public int random_sort(int[] arr, int start, int end) {
int random = start + new Random().nextInt(end - start + 1);
int key = arr[random];
int loop = start;
int front = random == start ? start + 1 : start;
while (loop <= end) {
if (loop == random) {
loop++;
continue;
}
if (arr[loop] < key) {
int temp = arr[loop];
arr[loop] = arr[front];
arr[front] = temp;
front = front + 1 == random ? front += 2 : front + 1;
}
loop++;
}
if (front < end) {
int temp = arr[random];
arr[random] = arr[front];
arr[front] = temp;
} else {
front = end;
}
return front;
}
// normal quick sort
public int sort(int[] arr, int start, int end) {
int loop = start;
int key = arr[start];
int front = start + 1;
while (loop <= end) {
if (key > arr[loop]) {
int temp = arr[loop];
arr[loop] = arr[front];
arr[front++] = temp;
}
loop++;
}
if (front != 1) {
int temp = arr[front - 1];
arr[front - 1] = arr[start];
arr[start] = temp;
}
return front - 1;
}
// shuffle the Array
public void shuffle(int[] arr) {
int length = arr.length;
int random_num = 0;
for (int i = 0; i < length; i++) {
random_num = new Random().nextInt(length);
int temp = arr[i];
arr[i] = arr[random_num];
arr[random_num] = temp;
}
}
}

Java sorting: random gen numbers same as sorted numbers(in terms of order)

I have a program that sorts randomly generated numbers from least to greatest or greatest to least depending on the users choice. 2 problems are occurring.
When the user does Insertion Sorting with Descending, the randomly generated numbers and sorting numbers output like this for example:
Randomly Generated Numbers:
89 90 2 830 399
After sorting using the Insertion Sort, Using Descending Order, the array is:
89 90 2 830 399
It's weird because my other methods are EXACTLY the same, and they work fine, but for some reason this doesn't work.
Here is my code:
import javax.swing.*;
import java.lang.reflect.Array;
import java.util.Random;
public class RoutineSorter {
private static int[] generateRandomArray(int size, int randomMax) {
int[] array = new int[size];
Random randomGenerator = new Random();
for (int i = 0; i < size; i++) {
array[i] = randomGenerator.nextInt(randomMax);
}
return array;
}
public static void main(String[] args) {
int MethodChoice = Integer.parseInt(JOptionPane.showInputDialog("What method would you like to use to sort the random numbers" + "\n" + "1 - Selection Sort" + "\n" + "2 - Bubble Sort" + "\n" + "3 - Insertion Sort" + "\n" + "4 - Quick Sort"));
int iTotalCount = Integer.parseInt(JOptionPane.showInputDialog("What is the total number of integers?"));
int SortOrder = Integer.parseInt(JOptionPane.showInputDialog("1 - Ascending, " + "2 - Descending"));
int[] array = generateRandomArray(iTotalCount, 1001);
System.out.println("Randomly Generated number list: ");
for (int i: array) {
System.out.print(i + " ");
}
System.out.println("\n---------------------------------");
if (MethodChoice == 1) {
if (SortOrder == 2) {
selectionSortReverse(array);
System.out.println("After sorting using the Selection Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
selectionSort(array);
System.out.println("After sorting using the Selection Sort," + " the array is:");
}
} else if (MethodChoice == 2) {
if (SortOrder == 2) {
bubbleSortReverse(array);
System.out.println("After sorting using the Bubble Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
bubbleSort(array);
System.out.println("After sorting using the Bubble Sort," + " the array is:");
}
} else if (MethodChoice == 3) {
if (SortOrder == 2) {
insertionSortReverse(array);
System.out.println("After sorting using the Insertion Sort, " + "Using Descending Order" + " " + "the array is: ");
} else if (SortOrder == 1) {
insertionSort(array);
System.out.println("After sorting using the Insertion Sort," + " the array is:");
} else if (MethodChoice == 4) {
if (SortOrder == 2) {
}
}
for (int i: array) {
System.out.print(i + " ");
}
}
}
public static void quickSort(int data[], int low, int high) {
int partitionLoc;
if (low < high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static void quickSortReverse(int data[], int low, int high) {
int partitionLoc;
if (low > high) {
partitionLoc = partition(data, low, high);
quickSort(data, low, partitionLoc - 1);
quickSort(data, partitionLoc + 1, high);
}
}
public static int partition(int data2[], int left, int right) {
boolean moveLeft = true;
int separator = data2[left];
while (left < right) {
if (moveLeft == true) {
while ((data2[right] >= separator) && (left < right)) {
right--;
}
data2[left] = data2[right];
moveLeft = false;
} else {
while ((data2[left] <= separator) && (left < right)) {
left++;
}
data2[right] = data2[left];
moveLeft = true;
}
}
data2[left] = separator;
return left;
}
public static void bubbleSort(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] > data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void bubbleSortReverse(int data[]) {
//Loop to control number of passes
for (int pass = 1; pass < data.length; pass++) {
//Loop to control # of comparisons for length of array-1
for (int element = 0; element < data.length - 1; element++) {
//compare side-by-side elements and swap them if
//first element is greater than second element
if (data[element] < data[element + 1]) {
swap(data, element, element + 1); //call swap method
}
}
}
}
public static void swapBubble(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
public static void insertionSort(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] > insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
public static void selectionSort(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] < data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void selectionSortReverse(int data[]) {
int smallest;
for (int i = 0; i < data.length - 1; i++) {
smallest = i;
//see if there is a smaller number further in the array
for (int index = i + 1; index < data.length; index++) {
if (data[index] > data[smallest]) {
swap(data, smallest, index);
}
}
}
}
public static void swap(int array2[], int first, int second) {
int hold = array2[first];
array2[first] = array2[second];
array2[second] = hold;
}
}
In the method insertionSortReverse() there is the mistake at the beginning of the while loop:
while (moveItem < 0 &&
It should be
while (moveItem > 0 &&
I suppose...
I fixed it. The problem was my insertionSortReverse() subroutine, one of the signs was the wrong way, so I put it to the opposite.
BEFORE
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem < 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}
AFTER
public static void insertionSortReverse(int data[]) {
int insert;
for (int next = 1; next < data.length; next++) {
insert = data[next];
int moveItem = next;
while (moveItem > 0 && data[moveItem - 1] < insert) {
data[moveItem] = data[moveItem - 1];
moveItem--;
}
data[moveItem] = insert;
}
}

Sorting and Binary search using Java

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

Java BinarySearch

Can I get some help please? I have tried many methods to get this to work i got the array sorted and to print but after that my binary search function doesnt want to run and give me right results. It always gives me -1. Any help?
public class BinarySearch {
public static final int NOT_FOUND = -1;
public static int binarySearch(double[] a, double key) {
int low = 0;
int high = a.length -1;
int mid;
while (low<=high) {
mid = (low+high) /2;
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
}
return NOT_FOUND;
}
public static void main(String[] args) {
double key = 10.5, index;
double a[] ={10,5,4,10.5,30.5};
int i;
int l = a.length;
int j;
System.out.println("The array currently looks like");
for (i=0; i<a.length; i++)
System.out.println(a[i]);
System.out.println("The array after sorting looks like");
for (j=1; j < l; j++) {
for (i=0; i < l-j; i++) {
if (a[i] > a[i+1]) {
double temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
for (i=0;i < l;i++) {
System.out.println(a[i]);
}
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
}
}
you are not actually comparing with the array values. in
while (low <= high) {
mid = (low + high) / 2;
if (mid > key) {
high = mid - 1;
} else if (mid < key) {
low = mid + 1;
} else {
return mid;
}
}
Instead use this section
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] > key) {
high = mid - 1;
} else if (a[mid] < key) {
low = mid + 1;
} else {
return mid;
}
}
You were correct to find the indexes, but what you were doing is that you were just comparing index number with your key, which is obviously incorrect. When you write a[mid] you will actually compare your key with the number which is at index mid.
Also the last line of code is giving compile error, it should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
Here
if (mid > key)
high = mid -1;
else if (mid < key)
low = mid +1;
else
return mid;
You're comparing index to a value (key) in array. You should instead compare it to a[mid]
And,
System.out.println("Found " + key + " at " + binarySearch(double a[], key));
Should be
System.out.println("Found " + key + " at " + binarySearch(a, key));
public static double binarySearch(double[] a, double key) {
if (a.length == 0) {
return -1;
}
int low = 0;
int high = a.length-1;
while(low <= high) {
int middle = (low+high) /2;
if (b> a[middle]){
low = middle +1;
} else if (b< a[middle]){
high = middle -1;
} else { // The element has been found
return a[middle];
}
}
return -1;
}
int binarySearch(int list[], int lowIndex, int highIndex, int find)
{
if (highIndex>=lowIndex)
{
int mid = lowIndex + (highIndex - lowIndex)/2;
// If the element is present at the
// middle itself
if (list[mid] == find)
return mid;
// If element is smaller than mid, then
// it can only be present in left subarray
if (list[mid] > find)
return binarySearch(list, lowIndex, mid-1, find);
// Else the element can only be present
// in right subarray
return binarySearch(list, mid+1, highIndex, find);
}
// We reach here when element is not present
// in array
return -1;
}
I somehow find the iterative version not quite easy to read, recursion makes it nice and easy :-)
public class BinarySearch {
private static int binarySearchMain(int key, int[] arr, int start, int end) {
int middle = (end-start+1)/2 + start; //get index of the middle element of a particular array portion
if (arr[middle] == key) {
return middle;
}
if (key < arr[middle] && middle > 0) {
return binarySearchMain(key, arr, start, middle-1); //recurse lower half
}
if (key > arr[middle] && middle < arr.length-1) {
return binarySearchMain(key, arr, middle+1, end); //recurse higher half
}
return Integer.MAX_VALUE;
}
public static int binarySearch(int key, int[] arr) { //entry point here
return binarySearchMain(key, arr, 0, arr.length-1);
}
}
Here is a solution without heap. The same thing can be done in an array.
If we need to find 'k' largest numbers, we take an array of size 'k' populated with first k items from the main data source. Now, keep on reading an item, and place it in the result array, if it has a place.
public static void largestkNumbers() {
int k = 4; // find 4 largest numbers
int[] arr = {4,90,7,10,-5,34,98,1,2};
int[] result = new int[k];
//initial formation of elems
for (int i = 0; i < k; ++i) {
result[i] = arr[i];
}
Arrays.sort(result);
for ( int i = k; i < arr.length; ++i ) {
int index = binarySearch(result, arr[i]);
if (index > 0) {
// insert arr[i] at result[index] and remove result[0]
insertInBetweenArray(result, index, arr[i]);
}
}
}
public static void insertInBetweenArray(int[] arr, int index, int num) {
// insert num at arr[index] and remove arr[0]
for ( int i = 0 ; i < index; ++i ) {
arr[i] = arr[i+1];
}
arr[index-1] = num;
}
public static int binarySearch(int[] arr, int num) {
int lo = 0;
int hi = arr.length - 1;
int mid = -1;
while( lo <= hi ) {
mid = (lo+hi)/2;
if ( arr[mid] > num ) {
hi = mid-1;
} else if ( arr[mid] < num ) {
lo = mid+1;
} else {
return mid;
}
}
return mid;
}
int BinSearch(int[] array, int size, int value)
{
if(size == 0) return -1;
if(array[size-1] == value) return size-1;
if(array[0] == value) return 0;
if(size % 2 == 0) {
if(array[size-1] == value) return size-1;
BinSearch(array,size-1,value);
}
else
{
if(array[size/2] == value) return (size/2);
else if(array[size/2] > value) return BinSearch(array, (size/2)+1, value);
else if(array[size/2] < value) return (size/2)+BinSearch(array+size/2, size/2, value);
}
}
or
Binary Search in Array
/**
* Find whether 67 is a prime no
* Domain consists 25 of prime numbers
* Binary Search
*/
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
int min = 0,
mid,
max = primes.length,
key = 67,
count= 0;
boolean isFound = false;
while (!isFound) {
if (count < 6) {
mid = (min + max) / 2;
if (primes[mid] == key) {
isFound = true;
System.out.println("Found prime at: " + mid);
} else if (primes[mid] < key) {
min = mid + 1;
isFound = false;
} else if (primes[mid] > key) {
max = mid - 1;
isFound = false;
}
count++;
} else {
System.out.println("No such number");
isFound = true;
}
}
/**
HOPE YOU LIKE IT
A.K.A Binary Search
Take number array of 10 elements, input a number a check whether the number
is present:
**/
package array;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
class BinaryS
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter a number: ");
int n=Integer.parseInt(br.readLine());
int a[]={10,20,30,40,50,60,70,80,90,100};
int upper=a.length-1,lower=0,mid;
boolean found=false;
int pos=0;
while(lower<=upper)
{
mid=(upper+lower)/2;
if(n<a[mid])upper=mid-1;
else if(n>a[mid])lower=mid+1;
else
{
found=true;
pos=mid;
break;
}
}
if(found)System.out.println(n+" found at index "+pos);
else System.out.println(n+" not found in array");
}
}
Well I know I am posting this answer much later.
But according to me its always better to check boundary condition at first.
That will make your algorithm more efficient.
public static int binarySearch(int[] array, int element){
if(array == null || array.length == 0){ // validate array
return -1;
}else if(element<array[0] || element > array[array.length-1]){ // validate value our of range that to be search
return -1;
}else if(element == array[0]){ // if element present at very first element of array
return 0;
}else if(element == array[array.length-1]){ // if element present at very last element of array
return array.length-1;
}
int start = 0;
int end = array.length-1;
while (start<=end){
int midIndex = start + ((end-start)/2); // calculate midIndex
if(element < array[midIndex]){ // focus on left side of midIndex
end = midIndex-1;
}else if(element > array[midIndex]){// focus on right side of midIndex
start = midIndex+1;
}else {
return midIndex; // You are in luck :)
}
}
return -1; // better luck next time :(
}
static int binarySearchAlgorithm() {
// Array should be in sorted order. Mandatory requirement
int[] a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int lowIndex = 0;
int valueToFind = 8;
int highIndex = a.length - 1;
while (lowIndex <= highIndex) {
//Finding the midIndex;
int midIndex = (highIndex + lowIndex) / 2;
// Checking if midIndex value of array contains the value to be find.
if (a[midIndex] == valueToFind) {
return midIndex;
}
// Checking the mid Index value is less than the value to be find.
else if (a[midIndex] < valueToFind) {
// If Yes, changing the lowIndex value to midIndex value + 1;
lowIndex = midIndex + 1;
} else if (a[midIndex] > valueToFind) {
// If Yes, changing the highIndex value to midIndex value - 1;
highIndex = midIndex - 1;
} else {
return -1;
}
}
return -1;
}

Categories