├── .gitignore ├── README.md ├── algorithms ├── math │ ├── factorial │ │ ├── factorial.c │ │ ├── factorial.cpp │ │ ├── factorial.hs │ │ ├── factorial.php │ │ ├── factorial.rs │ │ └── factorial.ts │ ├── fibonacci │ │ ├── bottom-up.fibonacci.cpp │ │ ├── fibonacci.cpp │ │ └── recursive.fibonacci.cpp │ ├── shoelace │ │ └── shoelace.hs │ └── sieve-of-eratosthenes │ │ └── sieve-of-eratosthenes.ts ├── search │ └── binary-search │ │ ├── binary-search.c │ │ ├── binary-search.cpp │ │ ├── binary-search.php │ │ ├── binary-search.rs │ │ └── binary-search.ts ├── shuffling │ └── fisher-yates-shuffle │ │ ├── fisher-yates-shuffle.c │ │ ├── fisher-yates-shuffle.cpp │ │ ├── fisher-yates-shuffle.php │ │ └── fisher-yates-shuffle.ts └── sorting │ ├── bubble-sort │ ├── bubble-sort.c │ ├── bubble-sort.cpp │ ├── bubble-sort.hs │ ├── bubble-sort.php │ ├── bubble-sort.ts │ └── recursive.bubble-sort.cpp │ ├── gnome-sort │ ├── gnome-sort.c │ ├── gnome-sort.cpp │ └── gnome-sort.ts │ ├── insertion-sort │ ├── insertion-sort.c │ ├── insertion-sort.cpp │ ├── insertion-sort.hs │ ├── insertion-sort.php │ └── insertion-sort.ts │ ├── odd-even-sort │ ├── odd-even-sort.c │ ├── odd-even-sort.cpp │ ├── odd-even-sort.php │ └── odd-even-sort.ts │ ├── quicksort │ └── quicksort.ts │ └── shell-sort │ ├── shell-sort.c │ ├── shell-sort.cpp │ └── shell-sort.ts ├── banner.png └── data-structures ├── stack └── stack.ts └── undirected-graph └── undirected-graph.ts /.gitignore: -------------------------------------------------------------------------------- 1 | *.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### What's this project for? 4 | a hobby project to try out implementing some common algorithms and datastructres with different languages such as TS, C and Haskell. 5 | -------------------------------------------------------------------------------- /algorithms/math/factorial/factorial.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned long long factorial(int num); 5 | 6 | int main() { 7 | unsigned long long answer = factorial(10); 8 | printf("%llu\n", answer); 9 | return 0; 10 | } 11 | 12 | unsigned long long factorial(int num) { 13 | unsigned long long tmp = 1; 14 | for (int l = 1; l <= num; l++) 15 | tmp = tmp * l; 16 | return tmp; 17 | } -------------------------------------------------------------------------------- /algorithms/math/factorial/factorial.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | unsigned long long 4 | factorial(unsigned long long num) 5 | { 6 | if (num == 1) 7 | return num; 8 | return factorial(num - 1) * num; 9 | } 10 | 11 | int 12 | main() 13 | { 14 | unsigned long long num = 50; 15 | unsigned long long answer = factorial(num); 16 | printf("%llu\n", answer); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /algorithms/math/factorial/factorial.hs: -------------------------------------------------------------------------------- 1 | factorial :: (Integral n) => n -> n 2 | factorial n = product [1..n] 3 | 4 | main :: IO () 5 | main = do 6 | putStr "factorial 10 = " 7 | print (factorial 10) 8 | -------------------------------------------------------------------------------- /algorithms/math/factorial/factorial.php: -------------------------------------------------------------------------------- 1 | u64 { 2 | return if num == 1 { num } else { factorial(num-1) * num }; 3 | } 4 | 5 | fn main() { 6 | let result = factorial(6); 7 | println!("6! = {}", result); 8 | } -------------------------------------------------------------------------------- /algorithms/math/factorial/factorial.ts: -------------------------------------------------------------------------------- 1 | const factorial = (num) => (num === 1 ? num : num * factorial(num - 1)); 2 | 3 | const answer = factorial(10); 4 | console.log(answer); 5 | -------------------------------------------------------------------------------- /algorithms/math/fibonacci/bottom-up.fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define ll long long 6 | 7 | vector vec; 8 | 9 | ll 10 | fib(int n) 11 | { 12 | 13 | if (n <= 2) 14 | return n; 15 | 16 | else { 17 | vec.clear(); 18 | vec.push_back(1); 19 | vec.push_back(1); 20 | 21 | for (int i = 2; i < n; ++i) 22 | vec.push_back(vec.at(i - 2) + vec.at(i - 1)); 23 | 24 | return vec.at(n - 1); 25 | } 26 | } 27 | 28 | int 29 | main() 30 | { 31 | int n = 80; 32 | 33 | cout << fib(n) << endl; 34 | } -------------------------------------------------------------------------------- /algorithms/math/fibonacci/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define ll long long 6 | 7 | map memoMap; 8 | 9 | ll 10 | fib(int n) 11 | { 12 | ll tmp; 13 | 14 | if (n <= 1) 15 | return n; 16 | 17 | if (memoMap.find(n) != memoMap.end()) 18 | return memoMap[n]; 19 | 20 | else { 21 | tmp = fib(n - 1) + fib(n - 2); 22 | memoMap[n] = tmp; 23 | return tmp; 24 | } 25 | } 26 | 27 | int 28 | main() 29 | { 30 | int n = 43; 31 | 32 | cout << fib(n) << endl; 33 | } -------------------------------------------------------------------------------- /algorithms/math/fibonacci/recursive.fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int 5 | fib(int n) 6 | { 7 | if (n <= 1) 8 | return n; 9 | 10 | return fib(n - 1) + fib(n - 2); 11 | } 12 | 13 | int 14 | main() 15 | { 16 | int n = 40; 17 | 18 | cout << fib(n) << endl; 19 | } -------------------------------------------------------------------------------- /algorithms/math/shoelace/shoelace.hs: -------------------------------------------------------------------------------- 1 | import Data.Array 2 | 3 | data Vector = Point 4 | { x :: Int, 5 | y :: Int 6 | } 7 | 8 | instance Show Vector where 9 | show :: Vector -> String 10 | show (Point x y) = "X: " ++ show x ++ " Y: " ++ show y 11 | 12 | getPoint :: Int -> Int -> Vector 13 | getPoint = Point 14 | 15 | points :: [Vector] 16 | points = [getPoint 0 0, getPoint 3 8, getPoint 8 5, getPoint 12 10, getPoint 15 3] 17 | 18 | toDouble :: Int -> Double 19 | toDouble = fromIntegral 20 | 21 | getX :: Vector -> Double 22 | getX (Point x _) = toDouble x 23 | 24 | getY :: Vector -> Double 25 | getY (Point _ y) = toDouble y 26 | 27 | shoeLace' :: [Vector] -> Double 28 | shoeLace' [] = 0 29 | shoeLace' [vector] = 0 30 | shoeLace' (a : b : rest) = 31 | (getX a * getY b) - (getX b * getY a) + shoeLace' (b : rest) 32 | 33 | shoeLace :: [Vector] -> Double 34 | shoeLace vectors = abs (shoeLace' vectors / 2.0) 35 | 36 | main :: IO () 37 | main = do 38 | putStrLn "Points:" 39 | mapM_ print points 40 | putStrLn "" 41 | putStrLn "Result:" 42 | print (shoeLace points) 43 | -------------------------------------------------------------------------------- /algorithms/math/sieve-of-eratosthenes/sieve-of-eratosthenes.ts: -------------------------------------------------------------------------------- 1 | const sieveOfEratosthenes = (n: number) => { 2 | const numbers: Array = [...Array(n - 1)].map( 3 | (_, idx) => idx + 2 4 | ); 5 | 6 | for (let p = 0; p < n - 1; ++p) 7 | if (typeof numbers[p] === "number") 8 | for (let h = p + 2, x = h; x * h <= n; ++x) numbers[x * h - 2] = null; 9 | 10 | return numbers.filter((x) => typeof x === "number"); 11 | }; 12 | 13 | console.log("n:", 100, "\n"); 14 | console.log("Result:", sieveOfEratosthenes(100)); 15 | -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int binarySearch(const int arr[], int arrLength, int target, int start, int end); 4 | int getMiddleOfRange(int start, int end); 5 | 6 | int main() { 7 | const int sortedArr[] = {10, 17, 32, 83, 534, 865, 976, 1025, 1535, 1921}; 8 | const int sizeOfArr = sizeof(sortedArr) / sizeof(sortedArr[0]); 9 | const int target = 1535; 10 | const int result = binarySearch(sortedArr, sizeOfArr, target, -1, -1); 11 | 12 | printf("Result: %d\n", result); 13 | } 14 | 15 | int binarySearch(const int arr[], int arrLength, int target, int start, int end) { 16 | const int startPointer = start > -1 ? start : 0; 17 | const int endPointer = end > -1 ? end : arrLength; 18 | 19 | if (arrLength < 2) 20 | return 0; 21 | 22 | if (startPointer < endPointer) { 23 | const int middlePointer = getMiddleOfRange(startPointer, endPointer); 24 | 25 | if (arr[middlePointer] == target) 26 | return middlePointer; 27 | 28 | if (arr[middlePointer] > target) 29 | return binarySearch(arr, arrLength, target, startPointer, middlePointer - 1); 30 | if (arr[middlePointer] < target) 31 | return binarySearch(arr, arrLength, target, middlePointer + 1, endPointer); 32 | } 33 | 34 | return -1; 35 | } 36 | 37 | int getMiddleOfRange(int start, int end) { return (end - start) / 2 + start; } -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int binarySearch(const int arr[], int length, int target, int start = -1, 5 | int end = -1) { 6 | int startPointer = start > -1 ? start : 0; 7 | int endPointer = end > -1 ? end : length; 8 | 9 | if (length < 2) return 0; 10 | if (startPointer < endPointer) { 11 | int middlePointer = (endPointer - startPointer) / 2 + startPointer; 12 | if (arr[middlePointer] == target) return middlePointer; 13 | if (arr[middlePointer] > target) 14 | return binarySearch(arr, length, target, startPointer, middlePointer - 1); 15 | if (arr[middlePointer] < target) 16 | return binarySearch(arr, length, target, middlePointer + 1, endPointer); 17 | } 18 | 19 | return -1; 20 | } 21 | 22 | int main() { 23 | int arr[] = {10, 17, 32, 83, 534, 865, 976, 1025, 1535, 1921}; 24 | int result = binarySearch(arr, 10, 15235); 25 | if (result == -1) 26 | cout << "the target value is not in the array"; 27 | else 28 | cout << "Result: " << result << endl; 29 | } -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.php: -------------------------------------------------------------------------------- 1 | $target) return binarySearch($arr, $target, $start, $middlePtr - 1); 25 | return -1; 26 | } 27 | 28 | 29 | $sortedArr = getSortedArray(10); 30 | $result = binarySearch($sortedArr, 6); 31 | 32 | echo $result; 33 | -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.rs: -------------------------------------------------------------------------------- 1 | fn binary_search(list: &[T], target: T, first: usize, end: usize) -> Option { 2 | if first > end { 3 | return None; 4 | }; 5 | 6 | let middle = (end - first) / 2 + first; 7 | if list[middle] == target { 8 | return Some(middle); 9 | } 10 | if target < list[middle] { 11 | return binary_search(list, target, first, middle - 1); 12 | } 13 | if target > list[middle] { 14 | return binary_search(list, target, middle + 1, end); 15 | } 16 | return None; 17 | } 18 | 19 | fn main() { 20 | let test_array = [1, 6, 7, 10, 16, 18, 23, 27, 47, 73, 89, 90, 100, 744]; 21 | let target = 89; 22 | let test_array_len = test_array.len() - 1; 23 | println!("binary search input: {:?}", test_array); 24 | let binary_search_result = binary_search(&test_array, target, 0, test_array_len); 25 | println!("binary search result: {:?}", binary_search_result); 26 | } -------------------------------------------------------------------------------- /algorithms/search/binary-search/binary-search.ts: -------------------------------------------------------------------------------- 1 | const getSortedArray = (len: number) => [...Array(len)].map((_, i) => i + 1); 2 | 3 | interface GetMiddleOfRangeParams { 4 | start: number; 5 | end: number; 6 | } 7 | 8 | const getMiddleOfRange = ({ start, end }: GetMiddleOfRangeParams) => 9 | Math.ceil((end - start) / 2) + start; 10 | 11 | interface BinarySearchParams { 12 | arr: number[]; 13 | target: number; 14 | start?: number; 15 | end?: number; 16 | } 17 | 18 | const binarySearch = ({ arr, target, start, end }: BinarySearchParams) => { 19 | const arrLength = arr.length; 20 | const startP = start ?? 0; 21 | const endP = end ?? arrLength - 1; 22 | 23 | if (arrLength === 1) return arr[0] === target ? 0 : -1; 24 | 25 | const middle = getMiddleOfRange({ start: startP, end: endP }); 26 | 27 | if (target === arr[middle]) return middle; 28 | if (target < arr[middle]) 29 | return binarySearch({ arr, target, start: startP, end: middle - 1 }); 30 | if (target > arr[middle]) 31 | return binarySearch({ arr, target, start: middle + 1, end: endP }); 32 | 33 | return -1; 34 | }; 35 | 36 | const parseBinarySearchOutput = (position) => 37 | position > -1 ? `The Value Positions is: ${position}` : `Nou Found!`; 38 | 39 | const tmpArr = getSortedArray(10); 40 | const answer = parseBinarySearchOutput( 41 | binarySearch({ arr: tmpArr, target: 8 }) 42 | ); 43 | console.log(answer); 44 | -------------------------------------------------------------------------------- /algorithms/shuffling/fisher-yates-shuffle/fisher-yates-shuffle.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void printArr(int arr[], size_t arrLength) { 6 | for (int x = 0; x < arrLength; x++) 7 | printf("%i, ", arr[x]); 8 | printf("\n"); 9 | } 10 | 11 | void fisherYatesShuffle(int list[], int length) { 12 | int j = length - 1; 13 | while (j > 0) { 14 | int r = rand() % j; 15 | int t = list[j]; 16 | list[j] = list[r]; 17 | list[r] = t; 18 | --j; 19 | } 20 | } 21 | 22 | int main() { 23 | srand(time(0)); 24 | int list[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; 25 | int length = sizeof(list) / sizeof(int); 26 | printArr(list, length); 27 | fisherYatesShuffle(list, length); 28 | printArr(list, length); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /algorithms/shuffling/fisher-yates-shuffle/fisher-yates-shuffle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | template 6 | void 7 | printArray(T const (&l)[n]) 8 | { 9 | for (int x = 0; x < n; ++x) 10 | cout << l[x] << ", "; 11 | } 12 | 13 | void 14 | fisherYatesShuffle(int l[], int n, int i = -1) 15 | { 16 | if (i == -1) { 17 | fisherYatesShuffle(l, n, n - 1); 18 | srand(time(0)); 19 | } else if (i > 1) { 20 | swap(l[i], l[rand() % i]); 21 | fisherYatesShuffle(l, n, i - 1); 22 | } 23 | } 24 | 25 | int 26 | main() 27 | { 28 | int sortedArr[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 29 | cout << "Sorted array:" << endl; 30 | printArray(sortedArr); 31 | cout << endl << endl << "Shuffled array:" << endl; 32 | fisherYatesShuffle(sortedArr, 10); 33 | printArray(sortedArr); 34 | cout << endl; 35 | return 0; 36 | } 37 | -------------------------------------------------------------------------------- /algorithms/shuffling/fisher-yates-shuffle/fisher-yates-shuffle.php: -------------------------------------------------------------------------------- 1 | 0) { 8 | $randomIndex = rand(0, $pointer); 9 | $tmp = $lc[$pointer]; 10 | $lc[$pointer] = $lc[$randomIndex]; 11 | $lc[$randomIndex] = $tmp; 12 | --$pointer; 13 | } 14 | return $lc; 15 | } 16 | 17 | $list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 18 | 19 | echo "Sorted List:\n"; 20 | print_r($list); 21 | echo "\n"; 22 | echo "Shuffled List:\n"; 23 | print_r(fisherYatesShuffle($list)); 24 | -------------------------------------------------------------------------------- /algorithms/shuffling/fisher-yates-shuffle/fisher-yates-shuffle.ts: -------------------------------------------------------------------------------- 1 | type FisherYatesShuffleParams = { 2 | list: unknown[]; 3 | pointer?: number; 4 | }; 5 | 6 | const fisherYatesShuffle = ({ list, pointer }: FisherYatesShuffleParams) => { 7 | if (pointer === undefined) 8 | return fisherYatesShuffle({ list, pointer: list.length - 1 }); 9 | if (pointer < 1) return list; 10 | const randomIndex = Math.floor(Math.random() * (pointer + 1)); 11 | const arr = list.slice(); 12 | [arr[pointer], arr[randomIndex]] = [arr[randomIndex], arr[pointer]]; 13 | console.log(pointer, randomIndex); 14 | return fisherYatesShuffle({ list: arr, pointer: pointer - 1 }); 15 | }; 16 | 17 | const aDummySortedList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; 18 | console.log("Input: ", aDummySortedList); 19 | console.log("output:", fisherYatesShuffle({ list: aDummySortedList })); 20 | -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/bubble-sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static int datasetArr[] = {25, 45, 1, 33, 68, 13, 57, 15, 7 | 85, 15, 83, 10, 6, 8, 2}; 8 | void bubbleSort(int arr[], size_t arrLength, char *direction); 9 | bool shouldSwap(int a, int b, char *direction); 10 | void swap(int *a, int *b); 11 | void printArr(int arr[], size_t arrLength); 12 | 13 | int main() { 14 | const size_t arrSize = sizeof(datasetArr) / sizeof(datasetArr)[0]; 15 | printf("Input:\n"); 16 | printArr(datasetArr, arrSize); 17 | 18 | bubbleSort(datasetArr, arrSize, "ASC"); 19 | 20 | printf("Output:\n"); 21 | printArr(datasetArr, arrSize); 22 | return 0; 23 | } 24 | 25 | void bubbleSort(int arr[], size_t arrLength, char *direction) { 26 | bool isSorted = false; 27 | 28 | while (!isSorted) { 29 | isSorted = true; 30 | for (int y = 0; y < (arrLength - 1); y++) { 31 | if (shouldSwap(arr[y], arr[y + 1], direction)) { 32 | swap(&arr[y], &arr[y + 1]); 33 | isSorted = false; 34 | } 35 | } 36 | }; 37 | } 38 | 39 | bool shouldSwap(int a, int b, char *direction) { 40 | if (strcmp(direction, "ASC") == 0) { 41 | return a > b; 42 | } 43 | return a < b; 44 | } 45 | 46 | void swap(int *a, int *b) { 47 | *a = *a + *b; 48 | *b = *a - *b; 49 | *a = *a - *b; 50 | } 51 | 52 | void printArr(int arr[], size_t arrLength) { 53 | for (int x = 0; x < arrLength; x++) 54 | printf("%i, ", arr[x]); 55 | printf("\n"); 56 | } -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/bubble-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | bubbleSort(int a[], int l) 5 | { 6 | for (int x = 0; x < l - 1; ++x) { 7 | int s = true; 8 | for (int y = 0; y < l - x - 1; ++y) { 9 | int current = a[y]; 10 | int next = a[y + 1]; 11 | 12 | if (current > next) { 13 | a[y + 1] = current; 14 | a[y] = next; 15 | s = false; 16 | } 17 | } 18 | if (s) 19 | break; 20 | } 21 | } 22 | 23 | void 24 | printArray(int a[], int l) 25 | { 26 | int x = 0; 27 | while (x < l) { 28 | std::cout << a[x]; 29 | std::cout << ", "; 30 | ++x; 31 | } 32 | } 33 | 34 | 35 | int main() 36 | { 37 | //int arr[] = { 6, 4, 8, 3, 2, 9, 0, 1, 7, 6, 5 }; 38 | int arr[] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; 39 | int arrLength = sizeof(arr) / sizeof(arr[0]); 40 | 41 | std::cout << "Input Array:" << std::endl; 42 | printArray(arr, arrLength); 43 | std::cout << std::endl << std::endl; 44 | std::cout << "Output Array:" << std::endl; 45 | bubbleSort(arr, arrLength); 46 | printArray(arr, arrLength); 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/bubble-sort.hs: -------------------------------------------------------------------------------- 1 | bubbleUp :: Ord a => [a] -> [a] 2 | bubbleUp [] = [] 3 | bubbleUp [x] = [x] 4 | bubbleUp (x : y : xs) 5 | | x > y = y : bubbleUp (x : xs) 6 | | otherwise = x : bubbleUp (y : xs) 7 | 8 | bubbleSort :: Ord a => [a] -> [a] 9 | bubbleSort list = foldl (\acc _ -> bubbleUp acc) list [0 .. length list] 10 | 11 | myList :: [Integer] 12 | myList = [9, 5, 6, 3, 1, 8, 4, 7, 2] 13 | 14 | main :: IO () 15 | main = do 16 | putStrLn "Input:" 17 | print myList 18 | putStrLn "" 19 | putStrLn "Output:" 20 | print (bubbleSort myList) -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/bubble-sort.php: -------------------------------------------------------------------------------- 1 | $b : $a < $b; 13 | } 14 | 15 | function swap($keyA, $keyB, $arr) 16 | { 17 | $tmpArr = array_replace([], $arr); 18 | [$tmpArr[$keyA], $tmpArr[$keyB]] = [$tmpArr[$keyB], $tmpArr[$keyA]]; 19 | 20 | return $tmpArr; 21 | } 22 | 23 | function bubbleSort($arr, $dir) 24 | { 25 | $cpyArr = array_replace([], $arr); 26 | $arrLength = count($cpyArr); 27 | 28 | for ($x = 0; $x < $arrLength; $x++) 29 | for ($y = 0; $y < ($arrLength - 1 - $x); $y++) { 30 | $currentVal = $cpyArr[$y]; 31 | $nextVal = $cpyArr[$y + 1]; 32 | if (shouldSwap($currentVal, $nextVal, $dir)) { 33 | $cpyArr = swap($y, $y + 1, $cpyArr); 34 | } 35 | } 36 | 37 | return $cpyArr; 38 | } 39 | 40 | $testArray = getTestArray(20); 41 | 42 | echo "Input:\n"; 43 | print_r($testArray); 44 | 45 | echo "\n"; 46 | 47 | echo "Output:\n"; 48 | print_r(bubbleSort($testArray, "ASC")); 49 | -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/bubble-sort.ts: -------------------------------------------------------------------------------- 1 | const getRandomNumber = () => Math.round(Math.random() * 100); 2 | const getRandomArray = (size: number) => [...Array(size)].map(getRandomNumber); 3 | 4 | const swap = (indexA: number, indexB: number, arr: number[]): number[] => { 5 | const tmpArr = [...arr]; 6 | [tmpArr[indexA], tmpArr[indexB]] = [tmpArr[indexB], tmpArr[indexA]]; 7 | return tmpArr; 8 | }; 9 | 10 | type DirectionType = "ASC" | "DESC"; 11 | const shouldSwap = (a: number, b: number, direction: DirectionType) => 12 | direction === "ASC" ? a > b : a < b; 13 | 14 | const bubbleSort: (numArr: number[], direction?: DirectionType) => number[] = ( 15 | numArr, 16 | direction = "ASC" 17 | ) => { 18 | let cpyArr = [...numArr]; 19 | const arrLength = cpyArr.length; 20 | 21 | cpyArr.forEach((_, index) => { 22 | for (let y = 0; y < arrLength - index - 1; y++) 23 | if (shouldSwap(cpyArr[y], cpyArr[y + 1], direction)) 24 | cpyArr = swap(y, y + 1, cpyArr); 25 | }); 26 | 27 | return cpyArr; 28 | }; 29 | 30 | const randomArr = getRandomArray(10); 31 | console.log("Input:", randomArr); 32 | console.log("output:", bubbleSort(randomArr)); 33 | -------------------------------------------------------------------------------- /algorithms/sorting/bubble-sort/recursive.bubble-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void bubbleSort(int arr[], int n) { 5 | if (n == 1) return; 6 | 7 | bool isSorted = true; 8 | for (int i = 0; i < n - 1; ++i) 9 | if (arr[i] > arr[i + 1]) { 10 | swap(arr[i], arr[i + 1]); 11 | isSorted = false; 12 | } 13 | 14 | if (isSorted) return; 15 | else bubbleSort(arr, n - 1); 16 | } 17 | 18 | int main() { 19 | int arr[] = {12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 20 | int arrLength = sizeof(arr) / sizeof(arr[0]); 21 | 22 | std::cout << "Input Array:" << std::endl; 23 | for (int x : arr) cout << x << ", "; 24 | std::cout << std::endl << std::endl; 25 | std::cout << "Output Array:" << std::endl; 26 | bubbleSort(arr, arrLength); 27 | for (int x : arr) cout << x << ", "; 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /algorithms/sorting/gnome-sort/gnome-sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int list[] = {2, 56, 66, 51, 82, 512, 92, 3, 8, 5, 8, 0, 11, 36, 437}; 4 | void gnomeSort(int l[], int s); 5 | void printArr(int arr[], size_t arrLength); 6 | 7 | int main() { 8 | int listSize = sizeof(list) / sizeof(list[0]); 9 | gnomeSort(list, listSize); 10 | printArr(list, listSize); 11 | return 0; 12 | } 13 | 14 | void gnomeSort(int l[], int s) { 15 | if (s < 2) 16 | return; 17 | int p = 1; 18 | while (p < s) 19 | if (p == 0) 20 | ++p; 21 | else if (l[p] < l[p - 1]) { 22 | int t = l[p]; 23 | l[p] = l[p - 1]; 24 | l[p - 1] = t; 25 | --p; 26 | } else 27 | ++p; 28 | } 29 | 30 | void printArr(int arr[], size_t arrLength) { 31 | for (int x = 0; x < arrLength; x++) 32 | printf("%i, ", arr[x]); 33 | printf("\n"); 34 | } -------------------------------------------------------------------------------- /algorithms/sorting/gnome-sort/gnome-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void gnomeSort(int l[], size_t n) { 5 | if (n < 2) return; 6 | size_t p = 1; 7 | while (p < n) { 8 | if (p == 0) { 9 | ++p; 10 | } else if (l[p] < l[p - 1]) { 11 | swap(l[p], l[p - 1]); 12 | --p; 13 | } else { 14 | ++p; 15 | } 16 | } 17 | } 18 | 19 | int main() { 20 | int list[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 21 | gnomeSort(list, 10); 22 | for (int x : list) cout << x << ", "; 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /algorithms/sorting/gnome-sort/gnome-sort.ts: -------------------------------------------------------------------------------- 1 | const swap = (list: number[], i1: number, i2: number): number[] => { 2 | const tmp = list.slice(); 3 | [tmp[i1], tmp[i2]] = [tmp[i2], tmp[i1]]; 4 | return tmp; 5 | }; 6 | 7 | type GnomeSort = (list: number[], pointer?: number) => number[]; 8 | const gnomeSort: GnomeSort = (list, pointer = 0) => { 9 | const listSize = list.length; 10 | const prevPointer = pointer - 1; 11 | const nextPointer = pointer + 1; 12 | 13 | if (listSize <= 1) return list; 14 | 15 | if (pointer > listSize - 1 || pointer < 0) throw Error(); 16 | if (pointer === 0) return gnomeSort(list, nextPointer); 17 | if (pointer === listSize - 1) return list; 18 | 19 | if (list[pointer] < list[prevPointer]) 20 | return gnomeSort(swap(list, pointer, prevPointer), prevPointer); 21 | return gnomeSort(list, nextPointer); 22 | }; 23 | 24 | const arr = Object.freeze([23, 73, 1, 3, 71, 10, 16, 63, 125, 52, 156, 22]); 25 | const res = gnomeSort(arr.slice(), 1); 26 | 27 | console.log("Dataset:", arr); 28 | console.log("Result:", res); 29 | -------------------------------------------------------------------------------- /algorithms/sorting/insertion-sort/insertion-sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | static int datasetArr[] = {61, 74, 9, 4, 95, 2, 81, 48, 7 | 14, 94, 33, 71, 84, 7, 1, 0}; 8 | void insertionSort(int arr[], size_t arrLength, char *direction); 9 | bool shouldSwap(int a, int b, char *direction); 10 | void swap(int *a, int *b); 11 | void printArr(int arr[], size_t arrLength); 12 | 13 | int main() { 14 | const size_t arrSize = sizeof(datasetArr) / sizeof(datasetArr)[0]; 15 | printf("Input:\n"); 16 | printArr(datasetArr, arrSize); 17 | 18 | insertionSort(datasetArr, arrSize, "ASC"); 19 | 20 | printf("Output:\n"); 21 | printArr(datasetArr, arrSize); 22 | return 0; 23 | } 24 | 25 | void insertionSort(int arr[], size_t arrLength, char *direction) { 26 | if (arrLength < 2) 27 | return; 28 | 29 | for (size_t j = 1; j < arrLength; j++) { 30 | const int currentVal = arr[j]; 31 | int prevPointer = j - 1; 32 | 33 | while (prevPointer >= 0 && 34 | shouldSwap(arr[prevPointer], currentVal, direction)) { 35 | swap(&arr[prevPointer], &arr[prevPointer + 1]); 36 | prevPointer--; 37 | } 38 | } 39 | } 40 | 41 | bool shouldSwap(int a, int b, char *direction) { 42 | if (strcmp(direction, "ASC") == 0) { 43 | return a > b; 44 | } 45 | return a < b; 46 | } 47 | 48 | void swap(int *a, int *b) { 49 | *a = *a + *b; 50 | *b = *a - *b; 51 | *a = *a - *b; 52 | } 53 | 54 | void printArr(int arr[], size_t arrLength) { 55 | for (int x = 0; x < arrLength; x++) 56 | printf("%i, ", arr[x]); 57 | printf("\n"); 58 | } -------------------------------------------------------------------------------- /algorithms/sorting/insertion-sort/insertion-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void insertionSort(int arr[], int n) { 5 | if (n < 2) return; 6 | for (int i = 1; i < n; ++i) { 7 | int c = arr[i]; 8 | int p = i - 1; 9 | while (p >= 0 && arr[p] > c) { 10 | swap(arr[p], arr[p + 1]); 11 | --p; 12 | } 13 | } 14 | } 15 | 16 | int main() { 17 | int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 18 | int length = sizeof(arr) / sizeof(int); 19 | cout << "Input: " << endl; 20 | for (int x : arr) { 21 | cout << x << ", "; 22 | } 23 | insertionSort(arr, length); 24 | cout << endl << endl << "Output: " << endl; 25 | for (int x : arr) { 26 | cout << x << ", "; 27 | } 28 | cout << endl; 29 | 30 | return 0; 31 | } -------------------------------------------------------------------------------- /algorithms/sorting/insertion-sort/insertion-sort.hs: -------------------------------------------------------------------------------- 1 | insert' :: Ord a => a -> [a] -> [a] 2 | insert' e [] = [e] 3 | insert' e xs@(x : xs') = 4 | case compare e x of 5 | GT -> x : insert' e xs' 6 | _ -> e : xs 7 | 8 | insertionSort :: Ord a => [a] -> [a] 9 | insertionSort = foldr insert' [] 10 | 11 | myList :: [Integer] 12 | myList = [9, 5, 6, 3, 1, 8, 4, 7, 2] 13 | 14 | main :: IO () 15 | main = do 16 | putStrLn "Input:" 17 | print myList 18 | putStrLn "" 19 | putStrLn "Output:" 20 | print (insertionSort myList) -------------------------------------------------------------------------------- /algorithms/sorting/insertion-sort/insertion-sort.php: -------------------------------------------------------------------------------- 1 | $b : $a < $b; 13 | } 14 | 15 | function swap($keyA, $keyB, $arr) 16 | { 17 | $tmpArr = array_replace([], $arr); 18 | [$tmpArr[$keyA], $tmpArr[$keyB]] = [$tmpArr[$keyB], $tmpArr[$keyA]]; 19 | 20 | return $tmpArr; 21 | } 22 | 23 | function insertionSort($arr, $dir) 24 | { 25 | $cpyArr = array_replace([], $arr); 26 | $arrLength = count($cpyArr); 27 | 28 | if ($arrLength <= 1) return $cpyArr; 29 | 30 | for ($j = 1; $j < $arrLength; $j++) { 31 | $currentVal = $cpyArr[$j]; 32 | $prevPointer = $j - 1; 33 | 34 | while ( 35 | $prevPointer >= 0 && shouldSwap($cpyArr[$prevPointer], $currentVal, $dir) 36 | ) { 37 | $cpyArr = swap($prevPointer, $prevPointer + 1, $cpyArr); 38 | --$prevPointer; 39 | } 40 | } 41 | 42 | return $cpyArr; 43 | } 44 | 45 | $testArray = getTestArray(20); 46 | 47 | echo "Input:\n"; 48 | print_r($testArray); 49 | 50 | echo "\n"; 51 | 52 | echo "Output:\n"; 53 | print_r(insertionSort($testArray, "ASC")); 54 | -------------------------------------------------------------------------------- /algorithms/sorting/insertion-sort/insertion-sort.ts: -------------------------------------------------------------------------------- 1 | const getRandomNumber = (max: number) => Math.round(Math.random() * (max * 10)); 2 | const getRandomArray = (size: number) => 3 | [...Array(size)].map(() => getRandomNumber(size)); 4 | 5 | const swap = (indexA: number, indexB: number, arr: number[]): number[] => { 6 | const tmpArr = [...arr]; 7 | [tmpArr[indexA], tmpArr[indexB]] = [tmpArr[indexB], tmpArr[indexA]]; 8 | return tmpArr; 9 | }; 10 | 11 | type DirectionType = "ASC" | "DESC"; 12 | const shouldSwap = (a: number, b: number, dir: DirectionType) => 13 | dir === "ASC" ? a > b : a < b; 14 | 15 | type InsertionSortType = (arr: number[], dir?: DirectionType) => any; 16 | const insertionSort: InsertionSortType = (arr, dir = "ASC") => { 17 | let cpyArr = [...arr]; 18 | const arrLength = cpyArr.length; 19 | 20 | if (arrLength <= 1) return cpyArr; 21 | 22 | for (let x = 1; x < arrLength; x++) { 23 | const currentVal = cpyArr[x]; 24 | let prevPointer = x - 1; 25 | 26 | while ( 27 | prevPointer >= 0 && 28 | shouldSwap(cpyArr[prevPointer], currentVal, dir) 29 | ) { 30 | cpyArr = swap(prevPointer, prevPointer + 1, cpyArr); 31 | prevPointer--; 32 | } 33 | } 34 | 35 | return cpyArr; 36 | }; 37 | 38 | const randomArr = getRandomArray(10); 39 | console.log("Input: ", randomArr); 40 | console.log("output:", insertionSort(randomArr, "ASC")); 41 | -------------------------------------------------------------------------------- /algorithms/sorting/odd-even-sort/odd-even-sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void printAray(int arr[], int n) { 5 | int x = 0; 6 | while (x < n) { 7 | printf("%i,", arr[x]); 8 | ++x; 9 | } 10 | printf("\n"); 11 | } 12 | 13 | void handleSwap(int arr[], int i, bool *isSorted) { 14 | if (arr[i] > arr[i + 1]) { 15 | int tmp = arr[i]; 16 | arr[i] = arr[i + 1]; 17 | arr[i + 1] = tmp; 18 | *isSorted = false; 19 | } 20 | } 21 | 22 | void oddEvenSort(int arr[], int n) { 23 | bool isSorted = false; 24 | 25 | while (!isSorted) { 26 | isSorted = true; 27 | 28 | for (int i = 1; i < n - 1; i = i + 2) 29 | handleSwap(arr, i, &isSorted); 30 | for (int i = 0; i < n - 1; i = i + 2) 31 | handleSwap(arr, i, &isSorted); 32 | } 33 | } 34 | 35 | int main() { 36 | int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 37 | int n = sizeof(arr) / sizeof(arr[0]); 38 | printf("Input\n"); 39 | printAray(arr, n); 40 | oddEvenSort(arr, n); 41 | printf("Output\n"); 42 | printAray(arr, n); 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /algorithms/sorting/odd-even-sort/odd-even-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | printAray(int arr[], int n) 5 | { 6 | int x = 0; 7 | while (x < n) { 8 | std::cout << arr[x] << ","; 9 | ++x; 10 | } 11 | } 12 | 13 | void 14 | handleSwap(int arr[], int i, bool* isSorted) 15 | { 16 | if (arr[i] > arr[i + 1]) { 17 | int tmp = arr[i]; 18 | arr[i] = arr[i + 1]; 19 | arr[i + 1] = tmp; 20 | *isSorted = false; 21 | } 22 | } 23 | 24 | void 25 | oddEvenSort(int arr[], int n) 26 | { 27 | bool isSorted = false; 28 | 29 | while (!isSorted) { 30 | isSorted = true; 31 | 32 | for (int i = 1; i < n - 1; i = i + 2) 33 | handleSwap(arr, i, &isSorted); 34 | for (int i = 0; i < n - 1; i = i + 2) 35 | handleSwap(arr, i, &isSorted); 36 | } 37 | } 38 | 39 | int 40 | main() 41 | { 42 | int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; 43 | int n = sizeof(arr) / sizeof(arr[0]); 44 | std::cout << "Input:\n"; 45 | printAray(arr, n); 46 | std::cout << "\n"; 47 | oddEvenSort(arr, n); 48 | std::cout << "Output:\n"; 49 | printAray(arr, n); 50 | return 0; 51 | } -------------------------------------------------------------------------------- /algorithms/sorting/odd-even-sort/odd-even-sort.php: -------------------------------------------------------------------------------- 1 | $lc[$i + 1]) { 11 | $tmp = $lc[$i]; 12 | $lc[$i] = $lc[$i + 1]; 13 | $lc[$i + 1] = $tmp; 14 | $s = false; 15 | } 16 | for ($i = 0; $i < count($lc) - 1; ++$i) 17 | if ($lc[$i] > $lc[$i + 1]) { 18 | $tmp = $lc[$i]; 19 | $lc[$i] = $lc[$i + 1]; 20 | $lc[$i + 1] = $tmp; 21 | $s = false; 22 | } 23 | } 24 | 25 | return $lc; 26 | } 27 | 28 | $list = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; 29 | 30 | echo "Input:\n"; 31 | print_r($list); 32 | 33 | echo "\n"; 34 | 35 | echo "Output:\n"; 36 | print_r(oddEvenSort($list)); -------------------------------------------------------------------------------- /algorithms/sorting/odd-even-sort/odd-even-sort.ts: -------------------------------------------------------------------------------- 1 | type OddEvenSortParams = { 2 | list: number[]; 3 | }; 4 | 5 | const oddEvenSort = ({ list }: OddEvenSortParams) => { 6 | const arrCpy = list.slice(); 7 | const length = arrCpy.length; 8 | let isSorted = false; 9 | 10 | const chk = (idx: number) => { 11 | if (arrCpy[idx] > arrCpy[idx + 1]) { 12 | [arrCpy[idx], arrCpy[idx + 1]] = [arrCpy[idx + 1], arrCpy[idx]]; 13 | isSorted = false; 14 | } 15 | }; 16 | 17 | while (!isSorted) { 18 | isSorted = true; 19 | for (let oddIndex = 1; oddIndex < length - 2; oddIndex = oddIndex + 2) 20 | chk(oddIndex); 21 | for (let evenIndex = 0; evenIndex < length - 1; evenIndex = evenIndex + 2) 22 | chk(evenIndex); 23 | } 24 | 25 | return arrCpy; 26 | }; 27 | 28 | const list = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]; 29 | console.log("Input:", list); 30 | console.log("Output:", oddEvenSort({ list })); 31 | -------------------------------------------------------------------------------- /algorithms/sorting/quicksort/quicksort.ts: -------------------------------------------------------------------------------- 1 | type DivideArray = ({ arr, pivot }: { arr: number[]; pivot: number }) => { 2 | lowerValues: number[]; 3 | higherValues: number[]; 4 | }; 5 | const divideArray: DivideArray = ({ arr, pivot }) => { 6 | const lowerValues: number[] = []; 7 | const higherValues: number[] = []; 8 | 9 | arr.forEach((val) => { 10 | if (val <= pivot) lowerValues.push(val); 11 | else higherValues.push(val); 12 | }); 13 | 14 | return { 15 | lowerValues, 16 | higherValues, 17 | }; 18 | }; 19 | 20 | type QuickSort = (arr: number[]) => number[]; 21 | const quickSort: QuickSort = (arr) => { 22 | const arrLength = arr.length; 23 | if (arrLength === 1) return arr; 24 | 25 | const arrWitoutPivot = arr.slice(0, arrLength - 1); 26 | const pivot = arr[arrLength - 1]; 27 | const { lowerValues, higherValues } = divideArray({ 28 | arr: arrWitoutPivot, 29 | pivot, 30 | }); 31 | 32 | const resultFilter = (section: number[]) => 33 | section.length > 1 ? quickSort(section) : section; 34 | 35 | return [...resultFilter(lowerValues), pivot, ...resultFilter(higherValues)]; 36 | }; 37 | 38 | const arr = [ 39 | 46, 61, 73, 93, 23, 64, 37, 93, 23, 62, 62, 13, 1, 6, 81, 7, 2, 9, 18, 643, 40 | ]; 41 | const result = quickSort(arr); 42 | 43 | console.log("Array:", arr); 44 | console.log("Sorted Array:", result); 45 | -------------------------------------------------------------------------------- /algorithms/sorting/shell-sort/shell-sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void shellSort(int arr[], int n) { 4 | int gap = n / 2; 5 | 6 | while (gap > 0) { 7 | for (int i = gap; i < n; i += 1) { 8 | int tmp = arr[i], x = i; 9 | for (; x >= gap && arr[x - gap] > tmp; x -= gap) arr[x] = arr[x - gap]; 10 | arr[x] = tmp; 11 | } 12 | 13 | gap /= 2; 14 | } 15 | } 16 | 17 | int main() { 18 | int arr[] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; 19 | int n = sizeof(arr) / sizeof(arr[0]); 20 | 21 | printf("Input\n"); 22 | for (int i : arr) printf("%i,", i); 23 | 24 | shellSort(arr, n); 25 | 26 | printf("\nOutput\n"); 27 | for (int i : arr) printf("%i,", i); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /algorithms/sorting/shell-sort/shell-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void 5 | shellSort(int arr[], int n) 6 | { 7 | int g = n / 2; 8 | while (g > 0) { 9 | for (int i = g; i < n; i += 1) { 10 | int tmp = arr[i], x; 11 | for (x = i; x >= g && arr[x - g] > tmp; x = x - g) 12 | arr[x] = arr[x - g]; 13 | arr[x] = tmp; 14 | } 15 | g = g / 2; 16 | } 17 | } 18 | 19 | int 20 | main() 21 | { 22 | int arr[] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; 23 | int n = sizeof(arr) / sizeof(arr[0]); 24 | cout << "Input:" << endl; 25 | for (int i : arr) 26 | cout << i << ", "; 27 | shellSort(arr, n); 28 | cout << endl << "Output:" <= gap && arrCpy[y - gap] > tmp; y = y - gap) 10 | arrCpy[y] = arrCpy[y - gap]; 11 | arrCpy[y] = tmp; 12 | } 13 | return shellSort(arrCpy, ~~(gap / 2)); 14 | } 15 | 16 | const input = [9, 5, 2, -125, 5, 6, 1, -4, -6, 7, 214, 516, 103, 0, 13]; 17 | console.log("Input:", input, "\n"); 18 | console.log("Output:", shellSort(input)); 19 | -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parsa-x86/algorithm-datastructure/b11b916944f51472785d9d566a39603c367560ef/banner.png -------------------------------------------------------------------------------- /data-structures/stack/stack.ts: -------------------------------------------------------------------------------- 1 | const initializeStack = >(initialValue: T) => { 2 | let _storage = [...initialValue]; 3 | 4 | const peekAll = () => _storage; 5 | 6 | const push = (item: unknown) => { 7 | _storage = [..._storage, item]; 8 | return peekAll(); 9 | }; 10 | 11 | const pop = () => { 12 | _storage = _storage.slice(0, _storage.length - 1); 13 | return peekAll(); 14 | }; 15 | 16 | const peek = () => { 17 | return _storage[_storage.length - 1]; 18 | }; 19 | 20 | const erase = () => { 21 | _storage = []; 22 | return _storage; 23 | }; 24 | 25 | return { 26 | peekAll, 27 | push, 28 | pop, 29 | peek, 30 | erase, 31 | }; 32 | }; 33 | 34 | const { erase, peek, peekAll, pop, push } = initializeStack([1, 2, "c"]); 35 | 36 | push(10); 37 | 38 | console.log(peekAll()); 39 | console.log(peek()); 40 | pop(); 41 | console.log(peekAll()); 42 | console.log(peek()); 43 | erase(); 44 | console.log(peekAll()); 45 | -------------------------------------------------------------------------------- /data-structures/undirected-graph/undirected-graph.ts: -------------------------------------------------------------------------------- 1 | type NodeName = string; 2 | 3 | const createUndirectedGraph = () => { 4 | const graph = new Map(); 5 | 6 | const addNode = (name: NodeName, value: unknown) => { 7 | graph.set(name, { value, adjacents: [] }); 8 | }; 9 | 10 | const addEdge = (node1: NodeName, node2: NodeName) => { 11 | if (!graph.has(node1)) throw new Error("Node 1 doesn't exists!"); 12 | if (!graph.has(node2)) throw new Error("Node 2 doesn't exists!"); 13 | 14 | const node1Data = graph.get(node1); 15 | const node2Data = graph.get(node2); 16 | 17 | if (node1Data.adjacents.includes(node2)) return; 18 | 19 | graph.set(node1, { 20 | ...node1Data, 21 | adjacents: [...node1Data.adjacents, node2], 22 | }); 23 | 24 | graph.set(node2, { 25 | ...node2Data, 26 | adjacents: [...node2Data.adjacents, node1], 27 | }); 28 | }; 29 | 30 | const removeEdge = (node1: NodeName, node2: NodeName) => { 31 | if (!graph.has(node1)) throw new Error("Node 1 doesn't exists!"); 32 | if (!graph.has(node2)) throw new Error("Node 2 doesn't exists!"); 33 | 34 | const node1Data = graph.get(node1); 35 | const node2Data = graph.get(node2); 36 | 37 | graph.set(node1, { 38 | ...node1Data, 39 | adjacents: node1Data.adjacents.filter((x) => x !== node2), 40 | }); 41 | 42 | graph.set(node2, { 43 | ...node2Data, 44 | adjacents: node2Data.adjacents.filter((x) => x !== node1), 45 | }); 46 | }; 47 | 48 | const removeNode = (node: NodeName) => { 49 | if (!graph.has(node)) return; 50 | graph.get(node).adjacents.forEach((x) => { 51 | const currentNodeData = graph.get(x); 52 | graph.set(x, { 53 | ...currentNodeData, 54 | adjacents: currentNodeData.adjacents.filter((item) => item !== node), 55 | }); 56 | }); 57 | graph.delete(node); 58 | }; 59 | 60 | return { 61 | addNode, 62 | removeNode, 63 | addEdge, 64 | removeEdge, 65 | getGraph: () => Object.fromEntries(graph), 66 | }; 67 | }; 68 | 69 | const { addNode, removeNode, addEdge, removeEdge, getGraph } = 70 | createUndirectedGraph(); 71 | 72 | console.log(getGraph()); 73 | 74 | addNode("tom", { name: "tom" }); 75 | addNode("sarah", { name: "sarah" }); 76 | addNode("alexander", { name: "sarah" }); 77 | 78 | addEdge("tom", "sarah"); 79 | addEdge("tom", "alexander"); 80 | 81 | console.log(getGraph()); 82 | 83 | removeEdge("tom", "sarah"); 84 | 85 | console.log(getGraph()); 86 | 87 | removeNode("alexander"); 88 | 89 | console.log(getGraph()); 90 | --------------------------------------------------------------------------------