Pure Programmer
Blue Matrix


Cluster Map

Project: Binary Search

You can easily and efficiently search through an array of values if they are ordered by using a [[Binary_search_algorithm|Binary Search]]. The idea is to check the middle value and determine if the search value is below or above that point. Either way you can eliminate half the possiblities with one check. Then repeat this procedure with the remaining values, eliminating half with each check until you find the value you are looking for. If N is the number of items in the array, you should be able to find the desired value with log₂N comparisons which is very fast.

Write a function that performs a Binary Search on a list for a specified value. Your main program should fills a list of integers with random values then perform various test searches on the list. Be sure to handle the edge cases where the search value is less than the first value, greater than the last value or if the value is not in the list at all.

Time how long it takes to generate N random integers, sort those N integers and search for those integers N times. Do this for N = 10³, 10⁴, 10⁵, 10⁶ and 10⁷. Then plot the results. Do the curves for generating, sorting and searching have different shapes?

The shape of these curves that describe the behavior of an algorithm as N gets larger are referred to using [[Big O notation]]. Typically algorithms are classified by Big O notations such as `O(1)`, `O(log x)`, `O(x)`, `O(x log x)`, `O(x^2)` or `O(x^3)`. These notations are listed in order of increasingly larger growth as N increases. If we had the choice to choose between two algorithms of `O(log x)` or `O(x)`, we would generally prefer the `O(log x)` since its execution time complexity grows more slowly then does `O(x)`. The most desireable is `O(1)` which is constant time. No matter the size of N, it always takes the same amount of time.

Comparision of Big O Functions
Comparision of Big O Functions

See Quicksort for a sort algorithm you can use for a sort function and LCGPseudorandomGenerator for a random number generator function.

Output
$ rustc BinarySearch.rs error: unknown format trait `d` --> BinarySearch.rs:85:39 | 85 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `d` --> BinarySearch.rs:91:39 | 91 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `d` --> BinarySearch.rs:104:39 | 104 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error[E0425]: cannot find function `exit` in this scope --> BinarySearch.rs:70:3 | 70 | exit(1); | ^^^^ not found in this scope | help: consider importing this function | 8 + use std::process::exit; | error[E0425]: cannot find value `Utils` in this scope --> BinarySearch.rs:72:29 | 72 | let mut sampleSize:isize = Utils.stoiWithDefault(args[1], 10); | ^^^^^ not found in this scope warning: denote infinite loops with `loop { ... }` --> BinarySearch.rs:30:2 | 30 | while true { | ^^^^^^^^^^ help: use `loop` | = note: `#[warn(while_true)]` on by default error[E0308]: mismatched types --> BinarySearch.rs:12:24 | 12 | let mut right:isize = list.len() - 1; | ----- ^^^^^^^^^^^^^^ expected `isize`, found `usize` | | | expected due to this | help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | 12 | let mut right:isize = (list.len() - 1).try_into().unwrap(); | + +++++++++++++++++++++ error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:15:11 | 15 | if list[m] < value { | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:17:18 | 17 | } else if list[m] > value { | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:27:25 | 27 | let pivot:isize = list[(high + low) / 2]; | ^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:33:14 | 33 | if !(list[i] < pivot) { break; } | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:37:14 | 37 | if !(list[j] > pivot) { break; } | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:42:25 | 42 | let temp:isize = list[j]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:43:8 | 43 | list[j] = list[i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:43:18 | 43 | list[j] = list[i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:44:8 | 44 | list[i] = temp; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0308]: mismatched types --> BinarySearch.rs:30:2 | 26 | fn partition(list:&mut Vec<isize>, low:isize, high:isize) -> isize { | ----- expected `isize` because of return type ... 30 | / while true { 31 | | loop { 32 | | i += 1; 33 | | if !(list[i] < pivot) { break; } ... | 44 | | list[i] = temp; 45 | | } | |_____^ expected `isize`, found `()` | note: the function expects a value to always be returned, but loops might run zero times --> BinarySearch.rs:30:2 | 30 | while true { | ^^^^^^^^^^ this might have zero elements to iterate on ... 40 | return j; | -------- if the loop doesn't execute, this value would never get returned = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility error[E0308]: mismatched types --> BinarySearch.rs:57:27 | 57 | quicksort0(&mut list, 0, list.len() - 1); | ---------- ^^^^^^^^^^^^^^ expected `isize`, found `usize` | | | arguments to this function are incorrect | note: function defined here --> BinarySearch.rs:48:4 | 48 | fn quicksort0(list:&mut Vec<isize>, low:isize, high:isize) -> () { | ^^^^^^^^^^ ---------- help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | 57 | quicksort0(&mut list, 0, (list.len() - 1).try_into().unwrap()); | + +++++++++++++++++++++ error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:76:22 | 76 | let mut start:i64 = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:84:21 | 84 | let mut stop:i64 = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:88:10 | 88 | start = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:90:9 | 90 | stop = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:94:10 | 94 | start = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:98:50 | 98 | let pos:isize = binarySearch(samples, samples[i]); | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:103:9 | 103 | stop = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error: aborting due to 24 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0308, E0425. For more information about an error, try `rustc --explain E0277`. $ rustc BinarySearch.rs error: unknown format trait `d` --> BinarySearch.rs:85:39 | 85 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `d` --> BinarySearch.rs:91:39 | 91 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error: unknown format trait `d` --> BinarySearch.rs:104:39 | 104 | println!("{}", format!("Duration: {0:d} ms", stop - start)); | ^ | = note: the only appropriate formatting traits are: - ``, which uses the `Display` trait - `?`, which uses the `Debug` trait - `e`, which uses the `LowerExp` trait - `E`, which uses the `UpperExp` trait - `o`, which uses the `Octal` trait - `p`, which uses the `Pointer` trait - `b`, which uses the `Binary` trait - `x`, which uses the `LowerHex` trait - `X`, which uses the `UpperHex` trait error[E0425]: cannot find function `exit` in this scope --> BinarySearch.rs:70:3 | 70 | exit(1); | ^^^^ not found in this scope | help: consider importing this function | 8 + use std::process::exit; | error[E0425]: cannot find value `Utils` in this scope --> BinarySearch.rs:72:29 | 72 | let mut sampleSize:isize = Utils.stoiWithDefault(args[1], 10); | ^^^^^ not found in this scope warning: denote infinite loops with `loop { ... }` --> BinarySearch.rs:30:2 | 30 | while true { | ^^^^^^^^^^ help: use `loop` | = note: `#[warn(while_true)]` on by default error[E0308]: mismatched types --> BinarySearch.rs:12:24 | 12 | let mut right:isize = list.len() - 1; | ----- ^^^^^^^^^^^^^^ expected `isize`, found `usize` | | | expected due to this | help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | 12 | let mut right:isize = (list.len() - 1).try_into().unwrap(); | + +++++++++++++++++++++ error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:15:11 | 15 | if list[m] < value { | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:17:18 | 17 | } else if list[m] > value { | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:27:25 | 27 | let pivot:isize = list[(high + low) / 2]; | ^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:33:14 | 33 | if !(list[i] < pivot) { break; } | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:37:14 | 37 | if !(list[j] > pivot) { break; } | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:42:25 | 42 | let temp:isize = list[j]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:43:8 | 43 | list[j] = list[i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:43:18 | 43 | list[j] = list[i]; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:44:8 | 44 | list[i] = temp; | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0308]: mismatched types --> BinarySearch.rs:30:2 | 26 | fn partition(list:&mut Vec<isize>, low:isize, high:isize) -> isize { | ----- expected `isize` because of return type ... 30 | / while true { 31 | | loop { 32 | | i += 1; 33 | | if !(list[i] < pivot) { break; } ... | 44 | | list[i] = temp; 45 | | } | |_____^ expected `isize`, found `()` | note: the function expects a value to always be returned, but loops might run zero times --> BinarySearch.rs:30:2 | 30 | while true { | ^^^^^^^^^^ this might have zero elements to iterate on ... 40 | return j; | -------- if the loop doesn't execute, this value would never get returned = help: return a value for the case when the loop has zero elements to iterate on, or consider changing the return type to account for that possibility error[E0308]: mismatched types --> BinarySearch.rs:57:27 | 57 | quicksort0(&mut list, 0, list.len() - 1); | ---------- ^^^^^^^^^^^^^^ expected `isize`, found `usize` | | | arguments to this function are incorrect | note: function defined here --> BinarySearch.rs:48:4 | 48 | fn quicksort0(list:&mut Vec<isize>, low:isize, high:isize) -> () { | ^^^^^^^^^^ ---------- help: you can convert a `usize` to an `isize` and panic if the converted value doesn't fit | 57 | quicksort0(&mut list, 0, (list.len() - 1).try_into().unwrap()); | + +++++++++++++++++++++ error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:76:22 | 76 | let mut start:i64 = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:84:21 | 84 | let mut stop:i64 = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:88:10 | 88 | start = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:90:9 | 90 | stop = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:94:10 | 94 | start = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error[E0277]: the type `[isize]` cannot be indexed by `isize` --> BinarySearch.rs:98:50 | 98 | let pos:isize = binarySearch(samples, samples[i]); | ^ slice indices are of type `usize` or ranges of `usize` | = help: the trait `SliceIndex<[isize]>` is not implemented for `isize` = help: the trait `SliceIndex<[T]>` is implemented for `usize` = note: required for `Vec<isize>` to implement `Index<isize>` error[E0425]: cannot find function `clock_millis` in this scope --> BinarySearch.rs:103:9 | 103 | stop = clock_millis(); | ^^^^^^^^^^^^ not found in this scope error: aborting due to 24 previous errors; 1 warning emitted Some errors have detailed explanations: E0277, E0308, E0425. For more information about an error, try `rustc --explain E0277`.

Solution