Notes-TheAlgorithmDesignManual/GrokkingAlgorithms.org

2.5 KiB

Notes & Exercises: Grokking Algorithms

Algorithms from the book

Recursive sum

OCaml

let rec sum_rec = function
  | [] -> 0
  | n::ns -> n + sum_rec ns;;

sum_rec [2;3;4;2;1];;
12
let sum_rec_tail list =
  let rec f acc = function
  | [] -> 0
  | n::ns -> sum_rec (acc + n) ns
  in f 0 list;;

sum_rec [2;3;4;2;1];;
12

Python

def sum_rec(arr):
    if not arr:
        return 0
    else:
        return arr[0] + sum_rec(arr[1:])

print(sum_rec([1,2,3]))
6

Binary Search

OCaml

let binary_search items target =
  let rec f low high =
    match (high - low) / 2 + low with
    | mid when target = items.(mid) -> Some items.(mid)
    | mid when target < items.(mid) -> f low mid
    | mid when target > items.(mid) -> f mid high
    | _ -> None
  in f 0 (Array.length items);;

binary_search [|1;2;3;4;5|] 3;;

Selection Sort

Runtime O(n2)

Python

def selection_sort(arr):
    sorted_list = []
    for i in range(len(arr)):
        max = arr[0]
        for count, value in enumerate(arr):
            if value > max:
                max = value
        sorted_list.append(max)
        arr.remove(max)
    return sorted_list

selection_sort([2,1,5,3,4])

OCaml

Really reinventing the wheel on this one…

let max_element = function
  | [] -> invalid_arg "empty list"
  | x::xs ->
     let rec f acc = function
       | [] -> acc
       | x::xs -> f (if x > acc then x else acc) xs
     in f x xs

let remove item list = 
  let rec f acc item = function
    | [] -> List.rev acc
    | x::xs -> if item = x then (List.rev acc) @ xs else f (x::acc) item xs
  in f [] item list

let selection_sort list =
  let rec f acc = function
    | [] -> acc
    | xs ->
       let m = max xs
       in f (m::acc) (remove m xs)
  in f [] list

Quicksort

Python

import random

def quicksort(arr):
    if len(arr) < 2:
        return arr
    elif len(arr) == 2:
        if arr[0] > arr[1]:
            temp = arr[1]
            arr[1] = arr[0]
            arr[0] = temp
        return arr
    else:
        # Pick a random pivot
        index = random.randrange(0, len(arr))
        pivot = arr.pop(index)
        left = [x for x in arr if x <= pivot]
        right = [x for x in arr if x > pivot]
        return quicksort(left) + [pivot] + quicksort(right)