Java: Binary Search - java

Is this an ok implementation of the binary search algorithm? It works but its an implementation I came up with and differs from my instructors. Can anyone punch a hole in it for me?
package algorithm.linearsearch;
public class BinarySearch {
public static void main(String[] args) {
System.out.println(binarySearch(
new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 26, 109, 1001, 1100 },
26));
}
private static int binarySearch(int[] array, int target) {
int p = 0;
int r = array.length - 1;
int q;
while (p <= r) {
q = (p + r) / 2;
if (array[q] == target) {
System.out.println("value: " + array[q]);
return q;
}
if (array[q] > target) {
r = q + 1;
} else {
p = q - 1;
}
}
return -1;
}
}

Just this
if (array[q] > target) {
r = q + 1;
} else {
p = q - 1;
}
should be
if (array[q] > target) {
r = q - 1; // index lower to current pivot
} else {
p = q + 1; // index upper to current pivot
}

One thing i can say. Your program is expected to return index if found or return -1 if not found. So you don't need to print value as its input taken from user regarding which element to find.
You need a check initially if your array is null return -1 to avoid null pointer exception which will happen when you calculate length of array.

Related

Jump search with Strings

i have been doing research on the jump search algorithm in an array. But i am confused on how you can use the search method with strings. Can anyone give me a link on where to look, or an example on here? Every example i have seen has been with numbers
public class JumpSearch
{
public static int jumpSearch(int[] arr, int x)
{
int n = arr.length;
int step = (int)Math.floor(Math.sqrt(n));
int prev = 0;
while (arr[Math.min(step, n)-1] < x)
{
prev = step;
step += (int)Math.floor(Math.sqrt(n));
if (prev >= n)
return -1;
}
while (arr[prev] < x)
{
prev++;
if (prev == Math.min(step, n))
return -1;
}
if (arr[prev] == x)
return prev;
return -1;
}
public static void main(String [ ] args)
{
int arr[] = { 0, 1, 1, 2, 3, 5, 8, 13, 21,
34, 55, 89, 144, 233, 377, 610};
int x = 55;
// Find the index of 'x' using Jump Search
int index = jumpSearch(arr, x);
System.out.println("\nNumber " + x +
" is at index " + index);
}
}

Find the largest drop between two numbers in an array. What is the time complexity of this code?

I have an array full of numbers. I need to find the maximum difference between 2 numbers but the biggest number is before the smallest number in the array.
public static int maximalDrop(int[] a)
For example:
for the array 5, 21, 3, 27, 12, 24, 7, 6, 4 the result will be 23 (27 - 4)
for the array 5, 21, 3, 22, 12, 7, 26, 14 the result will be 18 (21 - 3)
I think I write it in time complexity O(N) is my code ok? What is that time complexity of my code? Here is the method that I write:
public static int maximalDrop(int[] a) {
int i = 0;
int temp = 0;
int result = -1;
int k = a.length - 1;
boolean finishCheckLoop = false;
while (k > i) {
if (a[i] < a[i + 1] || finishCheckLoop == true) {
i++;
finishCheckLoop = false;
} else if (a[i] >= a[k] || a[i] <= a[k]) {
if (a[k] < 0)
temp = Math.abs(a[k]) + a[i];
else if (a[k] > 0)
temp = a[i] - a[k];
result = Math.max(temp, result);
k--;
}
if (i == k) {
k = a.length - 1;
finishCheckLoop = true;
}
}
return result;
}
Your code seems to be O(N), but it is quite complex for the task.
A simpler (and faster) version:
public static int maximalDrop(int[] a) {
int maxDrop = 0;
int drop = 0;
int max = Integer.MIN_VALUE;
int cur;
for (int i = 0; i < a.length; i++) {
cur = a[i];
if (cur > max) {
max = cur;
}
drop = max - cur;
if (drop > maxDrop) {
maxDrop = drop;
}
}
return maxDrop;
}
Disclaimer, I don't really write java, so I'm not sure if the Integer.MIN_VALUE is correct.
Yes, your code has a time complexity of O(N), but it's not readable and was probably hard to write.
Almost all of us have this bad tendency to start coding before we know how to solve the problem.
The code presented here seems like a product of this technique.
To improve the code, we should pick up a pen and paper and think simple. Note that we need to return the maximal drop from left to right so there are quite a few cases
Let's keep high, low and maximalDrop variables:
The current number is a new low:
low = current number.
Update the maximalDrop if necessary.
The current number is a new high - the previous low is irrelevant.
Else - do nothing.
Now it's easy to code:
public static int maximalDrop(int[] a) {
if (a.length == 0) {
return -1;
}
int h = a[0], l = a[0];
int maxDrop = -1;
for (int curr : a) {
if (curr < l) {
l = curr;
maxDrop = Math.max(h - l, maxDrop);
} else if (curr > h) {
h = curr;
l = Integer.MAX_VALUE;
}
}
return maxDrop;
}
Output examples:
System.out.println(maximalDrop(new int[]{5, 21, 3, 27, 12, 24, 7, 6, 4})); // 23
System.out.println(maximalDrop(new int[]{5, 21, 3, 22, 12, 7, 26, 14})); // 18
System.out.println(maximalDrop(new int[]{5, 6})); // -1

Binary Search implementation via java

Please see the below java source code for binary search implementation
public class Main {
public static void main(String[] args) {
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int y = binarySearch(x, 11);
System.out.println(y);
}
public static int binarySearch(int[] arr, int value) {
int searchedIndex = -1;
int first = 0;
int last = arr.length - 1;
int mid;
while (first <= last) {
mid = (first + last) / 2;
if (arr[mid] == value) {
searchedIndex = mid;
break;
} else {
if (value < arr[mid]) {
last = mid - 1;
} else {
first = mid + 1;
}
}
}
return searchedIndex;
}
}
int last = arr.length - 1 is -1 compulsory or not. I feel that code works fine either last = arr.length - 1. If its compulsory please explain why.
Arrays already have a method binarySearch you can just use :
int[] x = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
int r = Arrays.binarySearch(x, 11);
The -1 is needed for one very specific case: when you search for a value that is larger than the largest value in the array. For example, calling your function with
int y = binarySearch(x, 50);
will throw an ArrayOutOfBounds exception. That's because mid will eventually be equal to last, and without the -1, last is past the end of the array.

Debugging Max Heap in Java

Awhile back I was programming in C++ and I found a tutorial on making a max heap. This was the code and it seems to produce a correctly order heap.`
#include <iostream>
const int size = 14;
static int A[size] = {1, 2, 5, 10, 2, 11, 12, 7, 23, 22, 34, 54, 12, 22};
int left(int i)
{
return (2*i)+1;
}
int right(int i)
{
return (2*i)+2;
}
//a leaf of a value less than the size of the array
//and larger than the center of the array
bool isLeaf(int i)
{
if(i >= (size/2) && i <= size)
{
return true;
}
return false;
}
void maxHeapify(int i)
{
//if it isn't a leaf it may need to be swapped
if(!isLeaf(i))
{
//if the value is less than it's right or left child
if(A[i] < A[left(i)] || A[i] < A[right(i)])
{
//if the left child is smaller
if(A[left(i)] > A[right(i)])
{
//swap the left child with the index
std::cout << "Swapping " << A[i] << " and " << A[left(i)] << std::endl;
int a = A[i];
A[i] = A[left(i)];
A[left(i)] = a;
//and run maxHeapify in it. This will push the value to
//it's lowest point and order all things below the parent
maxHeapify(left(i));
}
else
{
//else swap with the right child since it is larger
std::cout << "Swapping " << A[i] << " and " << A[right(i)] << std::endl;
int a = A[i];
A[i] = A[right(i)];
A[right(i)] = a;
//run maxheap on that value. This will push the value to it's lowest position
maxHeapify(right(i));
}
}
}
}
bool buildHeap()
{
//need to run for each node that is not a leaf
for(int i = (size/2); i >= 0; i--)
{
maxHeapify(i);
}
return true;
}
int main()
{
std::cout << "before: " << std::endl;
for(int i = 0; i < size; i++)
{
std::cout << A[i] << ", ";
}
std::cout << std::endl;
buildHeap();
std::cout << "After: " << std::endl;
for(int i = 0; i < size; i++)
{
std::cout << A[i] << ",";
}
std::cout << std::endl;
return 0;
}
The output of the above is:
Before:
1, 2, 5, 10, 2, 11, 12, 7, 23, 22, 34, 54, 12, 22,
Swapping 12 and 22
Swapping 11 and 54
Swapping 2 and 34
Swapping 10 and 23
Swapping 5 and 54
Swapping 5 and 12
Swapping 2 and 34
Swapping 2 and 22
Swapping 1 and 54
Swapping 1 and 22
Swapping 1 and 12
After:
54,34,22,23,22,12,12,7,10,2,2,11,5,1,
Currently I am studying for a midterm and I am trying to reproduce my code in java. I have been looking at this for awhile and I can't seem to find where I am going wrong. Here is the broken java:
Main.java
public class Main {
/**
* #param args
*/
public static void main(String[] args) {
int[] a = { 1, 2, 5, 10, 2, 11, 12, 7, 23, 22, 34, 54, 12, 22 };
System.out.println("Begfore");
for (int i = 0; i < a.length; i++) {
System.out.print(a[i] + ", ");
}
Heap h = new Heap(a);
h.buildHeap();
h.print();
System.out.println();
System.out.println(a.length);
}
}
Heap.java
public class Heap {
int[] heap;
public Heap(int[] a) {
// heap = new int[a.length];
heap = a;
}
public void buildHeap() {
for (int i = heap.length / 2; i >= 0; i--) {
maxHeapify(i);
}
}
public int getLeft(int a) {
return (2 * a) + 1;
}
public int getRight(int a) {
return (2 * a) + 2;
}
private boolean isLeaf(int a) {
if (a >= ((heap.length) / 2) && a <= heap.length) {
return true;
} else {
return false;
}
}
public void maxHeapify(int a) {
if (!isLeaf(a)) {
if (heap[a] < heap[getLeft(a)] || heap[a] < heap[getRight(a)]) {
if (getLeft(a) <= heap.length && getRight(a) < heap.length) {
if (heap[getLeft(a)] > heap[getRight(a)]) {
int watcher = heap[a];
heap[a] = heap[getLeft(a)];
heap[getLeft(a)] = watcher;
maxHeapify(getLeft(a));
} else {
int watcher = heap[a];
heap[a] = heap[getRight(a)];
heap[getRight(a)] = watcher;
maxHeapify(getRight(a));
}
}
}
}
}
public void print() {
System.out.println("heap");
for (int i = 0; i < heap.length; i++) {
System.out.print(heap[i] + ", ");
}
}
}
Which doesn't produce a correct max ordered heap.
Java output: 54, 34, 12, 23, 22, 12, 1, 7, 10, 2, 2, 11, 5, 22,
This code has some Basic problems. Let me explain them.
First of all in Max Heapify function, you do not need to check for the condition that whether it is a leaf or not. This brings me to your max heapify function call.
The heapify function is always called from indices heap.length/2 - 1 to 0, notice that you have not used the -1. This allows the heapify to always be saved from the leaves because in a binary heap whether max on min, the leaves are placed at indices heap.length/2 to heap.length-1.
Another mistake with this code is with the way indices are used. There are 2 ways to use indices.
Either use real indices from 0 to heap.length -1 in this case there should not be any condition such as
<=heap.length or >=heap.length
But you have used conditions like this in you heapify code.
Or use fake indices which range from 1 to heap.length and whenever you use them inside [ ] just subtract -1. This works perfectly in my java code.
Hope this helps. I can give you the java code if you want.

how to print out the number of times a loop happened? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm am trying to determine how many comparisons are made for both the linear and binary searching techniques. can someone tell me how to print out the number of times a loop happened in each case? for example, to find 5 in the first array the loop happens only one time.
public static void main(String[] args) {
// TODO code application logic here
int[] values = {5, 8, 6, 2, 1, 7, 9, 3, 0, 4, 20, 50, 11, 22, 32, 120};
int[] valuesSorted = {1, 2, 3, 4, 5, 8, 16, 32, 51, 57, 59, 83, 90, 104};
DisplayArray(values);
DisplayArray(valuesSorted);
int index;
index = IndexOf(1, values);
System.out.println("1 is at values location " + index);
index = IndexOf(120, values);
System.out.println("120 is at values location " + index);
index = BinaryIndexOf(104, valuesSorted);
System.out.println("104 is at values Sorted location " + index);
index = BinaryIndexOf(90, valuesSorted);
System.out.println("90 is at values Sorted location " + index);
}
public static int IndexOf(int value, int[] array)
{
for (int i=0; i < array.length; i++)
{
if(array[i] == value)
return i;
}
return -1;
}
public static int BinaryIndexOf(int value, int [] array)
{
int start = 0;
int end = array.length -1;
int middle;
while (end >= start)
{
middle = (start + end ) /2;
if (array[middle]== value)
return middle;
if (array[middle]< value)
start = middle + 1;
else
end = middle - 1;
}
return -1;
}
public static void DisplayArray(int[] array)
{
for (int a : array)
{
System.out.print(a + " ");
}
System.out.println();
}
}
For the linear search, you can do something like this:
public static int IndexOf(int value, int[] array)
{
for (int i=0; i < array.length; i++)
{
if(array[i] == value)
{
System.out.println("Linear search: Number of comparisons = " + (i + 1));
return i;
}
}
return -1;
}
For the Binary Search, do this:
public static int BinaryIndexOf(int value, int [] array)
{
int start = 0;
int end = array.length -1;
int middle;
int loopCount = 0;
while (end >= start)
{
loopCount++;
middle = (start + end ) /2;
if (array[middle]== value)
{
System.out.println("Binary search: Number of times looped = " + loopCount);
return middle;
}
if (array[middle]< value)
start = middle + 1;
else
end = middle - 1;
}
System.out.println("Binary search: Number of times looped = " + loopCount);
return -1;
}
One easy way is to make a counter variable inside your class, and manipulate it as needed, like this:
private static int _loopCounter;
public static void main(String[] args) {
// TODO code application logic here
int[] values = {5, 8, 6, 2, 1, 7, 9, 3, 0, 4, 20, 50, 11, 22, 32, 120};
int[] valuesSorted = {1, 2, 3, 4, 5, 8, 16, 32, 51, 57, 59, 83, 90, 104};
DisplayArray(values);
DisplayArray(valuesSorted);
_loopCounter = 0;
int index;
index = IndexOf(1, values);
System.out.println("1 is at values location " + index);
System.out.println(_loopCounter + " comparisons were made.")
_loopCounter = 0;
index = IndexOf(120, values);
System.out.println("120 is at values location " + index);
System.out.println(_loopCounter + " comparisons were made.")
_loopCounter = 0;
index = BinaryIndexOf(104, valuesSorted);
System.out.println("104 is at values Sorted location " + index);
System.out.println(_loopCounter + " comparisons were made.")
_loopCounter = 0;
index = BinaryIndexOf(90, valuesSorted);
System.out.println("90 is at values Sorted location " + index);
System.out.println(_loopCounter + " comparisons were made.")
}
public static int IndexOf(int value, int[] array)
{
for (int i=0; i < array.length; i++)
{
_loopCounter++;
if(array[i] == value)
return i;
}
return -1;
}
public static int BinaryIndexOf(int value, int [] array)
{
int start = 0;
int end = array.length -1;
int middle;
while (end >= start)
{
_loopCounter++;
middle = (start + end ) /2;
if (array[middle]== value)
return middle;
if (array[middle]< value)
start = middle + 1;
else
end = middle - 1;
}
return -1;
}
public static void DisplayArray(int[] array)
{
for (int a : array)
{
System.out.print(a + " ");
}
System.out.println();
}
I didn't test this code, but I'll bet you can modify it to work how you want.

Categories

Resources