Refactored left searching algorithms (except SaddlebackSearch. Just cleaned the code in that algorithm)

Added some documentation to these algorithms
This commit is contained in:
nik 2018-04-12 17:29:33 +03:00
parent 7d178c51b4
commit 066adc71d5
8 changed files with 294 additions and 225 deletions

View File

@ -1,84 +0,0 @@
import java.util.*;
/**
* Program to perform Saddleback Search
* Given a sorted 2D array(elements are sorted across every row and column, assuming ascending order)
* of size n*m we can search a given element in O(n+m)
*
* we start from bottom left corner
* if the current element is greater than the given element then we move up
* else we move right
* Sample Input:
* 5 5 ->Dimensions
* -10 -5 -3 4 9
* -6 -2 0 5 10
* -4 -1 1 6 12
* 2 3 7 8 13
* 100 120 130 140 150
* 140 ->element to be searched
* output: 4 3 // first value is row, second one is column
*
* @author Nishita Aggarwal
*
*/
public class SaddlebackSearch {
/**
* This method performs Saddleback Search
*
* @param arr The **Sorted** array in which we will search the element.
* @param crow the current row.
* @param ccol the current column.
* @param ele the element that we want to search for.
*
* @return The index(row and column) of the element if found.
* Else returns -1 -1.
*/
static int[] search(int arr[][],int crow,int ccol,int ele){
//array to store the answer row and column
int ans[]={-1,-1};
if(crow<0 || ccol>=arr[crow].length){
return ans;
}
if(arr[crow][ccol]==ele)
{
ans[0]=crow;
ans[1]=ccol;
return ans;
}
//if the current element is greater than the given element then we move up
else if(arr[crow][ccol]>ele)
{
return search(arr,crow-1,ccol,ele);
}
//else we move right
return search(arr,crow,ccol+1,ele);
}
/**
* Main method
*
* @param args Command line arguments
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc=new Scanner(System.in);
int arr[][];
int i,j,rows=sc.nextInt(),col=sc.nextInt();
arr=new int[rows][col];
for(i=0;i<rows;i++)
{
for(j=0;j<col;j++){
arr[i][j]=sc.nextInt();
}
}
int ele=sc.nextInt();
//we start from bottom left corner
int ans[]=search(arr,rows-1,0,ele);
System.out.println(ans[0]+" "+ans[1]);
sc.close();
}
}

View File

@ -1,74 +0,0 @@
import java.util.Scanner;
public class TernarySearch{
/**
* @param arr The **Sorted** array in which we will search the element.
* @param value The value that we want to search for.
* @return The index of the element if found.
* Else returns -1.
*/
public static int ternarySearch(int[] arr, int value){
return ternarySearch(arr, value, 0, arr.length - 1);
}
/**
* @param arr The **Sorted** array in which we will search the element.
* @param key The value that we want to search for.
* @param start The starting index from which we will start Searching.
* @param end The ending index till which we will Search.
* @return Returns the index of the Element if found.
* Else returns -1.
*/
public static int ternarySearch(int[] arr, int key, int start, int end) {
if (start > end){
return -1;
}
/* First boundary: add 1/3 of length to start */
int mid1 = start + (end - start) / 3;
/* Second boundary: add 2/3 of length to start */
int mid2 = start + 2 * (end - start) / 3;
if (arr[mid1] == key) {
return mid1;
}
else if (arr[mid2] == key) {
return mid2;
}
/* Search the first (1/3) rd part of the array.*/
else if (key < arr[mid1]) {
return ternarySearch(arr, key, start, mid1 - 1);
}
/* Search 3rd (1/3)rd part of the array */
else if (key > arr[mid2]) {
return ternarySearch(arr, key, mid2 + 1, end);
}
/* Search middle (1/3)rd part of the array */
else {
return ternarySearch(arr, key, mid1, mid2);
}
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Enter number of elements in the array");
int n = s.nextInt();
int arr[] = new int[n];
System.out.println("Enter the elements of the Sorted array");
for (int i= 0; i < n; i++){
arr[i] = s.nextInt();
}
System.out.println("Enter element to search for : ");
int k = s.nextInt();
int ans = ternarySearch(arr, k);
if (ans == -1) {
System.out.println(" The element is not present in the array.");
}
else {
System.out.println("The element is present at the position " + (ans+1));
}
}
}

View File

@ -1,53 +0,0 @@
class Test
{
// Array of items on which search will
// be conducted.
static int arr[] = new int[]{10, 12, 13, 16, 18, 19, 20, 21, 22, 23,
24, 33, 35, 42, 47};
// If x is present in arr[0..n-1], then returns
// index of it, else returns -1.
static int interpolationSearch(int x)
{
// Find indexes of two corners
int lo = 0, hi = (arr.length - 1);
// Since array is sorted, an element present
// in array must be in range defined by corner
while (lo <= hi && x >= arr[lo] && x <= arr[hi])
{
// Probing the position with keeping
// uniform distribution in mind.
int pos = lo + (((hi-lo) /
(arr[hi]-arr[lo]))*(x - arr[lo]));
// Condition of target found
if (arr[pos] == x)
return pos;
// If x is larger, x is in upper part
if (arr[pos] < x)
lo = pos + 1;
// If x is smaller, x is in lower part
else
hi = pos - 1;
}
return -1;
}
// Driver method
public static void main(String[] args)
{
int x = 18; // Element to be searched
int index = interpolationSearch(x);
// If element was found
if (index != -1)
System.out.println("Element found at index " + index);
else
System.out.println("Element not found.");
}
}

View File

@ -1,8 +1,11 @@
package search;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;
import static java.lang.String.format;
/**
*
*
@ -70,8 +73,8 @@ class BinarySearch implements SearchAlgorithm {
//just generate data
Random r = new Random();
int size = 200;
int maxElement = 100;
int size = 100;
int maxElement = 100000;
Integer[] integers = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new);
@ -83,5 +86,9 @@ class BinarySearch implements SearchAlgorithm {
System.out.println(String.format("Should be found: %d. Found %d at index %d. An array length %d"
, shouldBeFound, integers[atIndex], atIndex, size));
int toCheck = Arrays.binarySearch(integers, shouldBeFound);
System.out.println(format("Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex));
}
}

View File

@ -0,0 +1,79 @@
package search;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.IntStream;
import static java.lang.String.format;
/**
*
* Interpolation search algorithm implementation
*
* Worst-case performance O(n)
* Best-case performance O(1)
* Average performance O(log(log(n))) if the elements are uniformly distributed if not O(n)
* Worst-case space complexity O(1)
*
*
* @author Podshivalov Nikita (https://github.com/nikitap492)
*
*/
class InterpolationSearch {
/**
* @param array is a sorted array
* @param key is a value what shoulb be found in the array
* @return an index if the array contains the key unless -1
*/
public int find(int array[], int key) {
// Find indexes of two corners
int start = 0, end = (array.length - 1);
// Since array is sorted, an element present
// in array must be in range defined by corner
while (start <= end && key >= array[start] && key <= array[end])
{
// Probing the position with keeping
// uniform distribution in mind.
int pos = start + (((end-start) / (array[end]-array[start]))*(key - array[start]));
// Condition of target found
if (array[pos] == key)
return pos;
// If key is larger, key is in upper part
if (array[pos] < key)
start = pos + 1;
// If key is smaller, x is in lower part
else
end = pos - 1;
}
return -1;
}
// Driver method
public static void main(String[] args) {
Random r = new Random();
int size = 100;
int maxElement = 100000;
int[] integers = IntStream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray();
//the element that should be found
Integer shouldBeFound = integers[r.nextInt(size - 1)];
InterpolationSearch search = new InterpolationSearch();
int atIndex = search.find(integers, shouldBeFound);
System.out.println(String.format("Should be found: %d. Found %d at index %d. An array length %d"
, shouldBeFound, integers[atIndex], atIndex, size));
int toCheck = Arrays.binarySearch(integers, shouldBeFound);
System.out.println(format("Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex));
}
}

View File

@ -2,6 +2,9 @@ package search;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;
import static java.lang.String.format;
/**
* Binary search is one of the most popular algorithms
@ -37,9 +40,9 @@ public final class IterativeBinarySearch implements SearchAlgorithm {
int l, r, k, cmp;
l = 0;
r = array.length;
r = array.length - 1;
while (l < r) {
while (l <= r) {
k = (l + r) / 2;
cmp = key.compareTo(array[k]);
@ -57,18 +60,23 @@ public final class IterativeBinarySearch implements SearchAlgorithm {
//Only a main method for test purpose
public static void main(String[] args) {
Random rand = new Random();
int base = rand.nextInt(1000);
Random r = new Random();
int size = 100;
int maxElement = 100000;
Integer[] integers = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new);
Integer[] array = new Integer[65535];
for (int i = 0; i < array.length; i++) {
array[i] = base + (i + 1);
}
//Arrays.sort(array); //if needed
Integer key = base + rand.nextInt(array.length * 2); //can generate keys that aren't in array
//the element that should be found
Integer shouldBeFound = integers[r.nextInt(size - 1)];
System.out.println(new IterativeBinarySearch().find(array, key));
System.out.println(Arrays.binarySearch(array, key));
IterativeBinarySearch search = new IterativeBinarySearch();
int atIndex = search.find(integers, shouldBeFound);
System.out.println(String.format("Should be found: %d. Found %d at index %d. An array length %d"
, shouldBeFound, integers[atIndex], atIndex, size));
int toCheck = Arrays.binarySearch(integers, shouldBeFound);
System.out.println(format("Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex));
}
}

View File

@ -0,0 +1,80 @@
package search;
import java.util.Scanner;
/**
* Program to perform Saddleback Search
* Given a sorted 2D array(elements are sorted across every row and column, assuming ascending order)
* of size n*m we can search a given element in O(n+m)
* <p>
* we start from bottom left corner
* if the current element is greater than the given element then we move up
* else we move right
* Sample Input:
* 5 5 ->Dimensions
* -10 -5 -3 4 9
* -6 -2 0 5 10
* -4 -1 1 6 12
* 2 3 7 8 13
* 100 120 130 140 150
* 140 ->element to be searched
* output: 4 3 // first value is row, second one is column
*
* @author Nishita Aggarwal
*/
public class SaddlebackSearch {
/**
* This method performs Saddleback Search
*
* @param arr The **Sorted** array in which we will search the element.
* @param row the current row.
* @param col the current column.
* @param key the element that we want to search for.
* @return The index(row and column) of the element if found.
* Else returns -1 -1.
*/
private static int[] find(int arr[][], int row, int col, int key) {
//array to store the answer row and column
int ans[] = {-1, -1};
if (row < 0 || col >= arr[row].length) {
return ans;
}
if (arr[row][col] == key) {
ans[0] = row;
ans[1] = col;
return ans;
}
//if the current element is greater than the given element then we move up
else if (arr[row][col] > key) {
return find(arr, row - 1, col, key);
}
//else we move right
return find(arr, row, col + 1, key);
}
/**
* Main method
*
* @param args Command line arguments
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int arr[][];
int i, j, rows = sc.nextInt(), col = sc.nextInt();
arr = new int[rows][col];
for (i = 0; i < rows; i++) {
for (j = 0; j < col; j++) {
arr[i][j] = sc.nextInt();
}
}
int ele = sc.nextInt();
//we start from bottom left corner
int ans[] = find(arr, rows - 1, 0, ele);
System.out.println(ans[0] + " " + ans[1]);
sc.close();
}
}

View File

@ -0,0 +1,106 @@
package search;
import java.util.Arrays;
import java.util.Random;
import java.util.stream.Stream;
import static java.lang.String.format;
/**
*
*
*
* A ternary search algorithm is a technique in computer science for finding the minimum or maximum of a unimodal function
* The algorithm determines either that the minimum or maximum cannot be in the first third of the domain
* or that it cannot be in the last third of the domain, then repeats on the remaining third.
*
* Worst-case performance Θ(log3(N))
* Best-case performance O(1)
* Average performance Θ(log3(N))
* Worst-case space complexity O(1)
*
*
* @author Podshivalov Nikita (https://github.com/nikitap492)
*
* @see SearchAlgorithm
* @see IterativeBinarySearch
*
*/
public class TernarySearch implements SearchAlgorithm{
/**
* @param arr The **Sorted** array in which we will search the element.
* @param value The value that we want to search for.
* @return The index of the element if found.
* Else returns -1.
*/
@Override
public <T extends Comparable<T>> int find(T[] arr, T value){
return ternarySearch(arr, value, 0, arr.length - 1);
}
/**
* @param arr The **Sorted** array in which we will search the element.
* @param key The value that we want to search for.
* @param start The starting index from which we will start Searching.
* @param end The ending index till which we will Search.
* @return Returns the index of the Element if found.
* Else returns -1.
*/
private <T extends Comparable<T>> int ternarySearch(T[] arr, T key, int start, int end) {
if (start > end){
return -1;
}
/* First boundary: add 1/3 of length to start */
int mid1 = start + (end - start) / 3;
/* Second boundary: add 2/3 of length to start */
int mid2 = start + 2 * (end - start) / 3;
if (key.compareTo(arr[mid1]) == 0) {
return mid1;
}
else if (key.compareTo(arr[mid2]) == 0) {
return mid2;
}
/* Search the first (1/3) rd part of the array.*/
else if (key.compareTo(arr[mid1]) < 0) {
return ternarySearch(arr, key, start, --mid1);
}
/* Search 3rd (1/3)rd part of the array */
else if (key.compareTo(arr[mid2]) > 0) {
return ternarySearch(arr, key, ++mid2, end);
}
/* Search middle (1/3)rd part of the array */
else {
return ternarySearch(arr, key, mid1, mid2);
}
}
public static void main(String[] args) {
//just generate data
Random r = new Random();
int size = 100;
int maxElement = 100000;
Integer[] integers = Stream.generate(() -> r.nextInt(maxElement)).limit(size).sorted().toArray(Integer[]::new);
//the element that should be found
Integer shouldBeFound = integers[r.nextInt(size - 1)];
TernarySearch search = new TernarySearch();
int atIndex = search.find(integers, shouldBeFound);
System.out.println(format("Should be found: %d. Found %d at index %d. An array length %d"
, shouldBeFound, integers[atIndex], atIndex, size));
int toCheck = Arrays.binarySearch(integers, shouldBeFound);
System.out.println(format("Found by system method at an index: %d. Is equal: %b", toCheck, toCheck == atIndex));
}
}