A repository that contains the Implementation of Data structures and Algorithms in Dart.
What is an Algorithm?
f: I => O
An algorithm is defined as a function that maps arbitrary-sized input to fixed-sized output. The function could be a single step or a series of steps. It can be applied just once, in an iteration or under recursion.
An algorithm has to be –
- Correct
- Efficient
Correctness –
The correctness of an algorithm is defined through Induction
. It follows the following steps –
- Base Case – We check the algorithm for the smallest number of inputs possible ie. 1
- Hypothesis – We assume that the algorithm is going to work for a random number of input n.
- Inductive Step – We check the correctness of the algorithm for input
n+1
.
Now that we have proved the correctness of the algorithm, let’s argue for efficiency.
Efficiency –
Efficiency defines how fast an algorithm runs and how fast it runs relative to all other possible approaches. Mathematically, we assume all processors have the same processing power and expect efficiency to depend upon the size of the input. If we were to plot it on the graph, it would be a value on y-axis(as a dependent variable), dependent on the size of the input(on x-axis).
We have a few functions that relate the algorithm’s input size to its performance.
- Constant Time –
O(c)
- Linear Time –
O(n)
- Logarithmic Time –
O(log(n))
- Logarithmic Linear Time –
O(n * log(n))
- Quadratic Time –
O(n^2)
- Polynomial Time –
O(n^c)
- Exponential Time –
2^(O(n))
Data Strcutures –
To understand Data Structures, we first need to understand our current model of computation –
We used to have 32-bit CPUs(processors), which allowed only 2^32 ie. 4 gigs of RAM(memory). Technology evolved and now we have 64-bits system which allows 2^64 ie. 20 exabytes of memory. But the CPU’s word size is still pretty small ie. 64 bits. They can perform –
- binary ops
- arithmetic ops
- bitwise ops
- read and write in memory
But what if we need to perform any operation on a data larger than 64 bits?
Thats what we need to Data Structures
for.
Data Structures
are used to operate on large amount of data. There are two ways to store data of a non-constant amount to perform operations on that information faster –
- Reduce the problems to Structurs you already know.
- Design your own Recursive Algorithms.
Following are the topics that comes under each of those ways –
1. Reeduce the problem to what you already know –
Search Problems –
- Static Array
- Linked List
- Dynamic Array
- Sorted Array
- Direct Access Array
- Hash Tables
- Balanced Binary Tree
- Binary Heap
Sort Algorithm –
- Insertion Sort
- Selection Sort
- Merge Sort
- Counting Sort
- Radix Sort
- AVL Sort
- Heap Sort
Shortest Path Algorithm –
- Breadth First Search
- DAG Relaxation
- Depth First Search
- Topological Sort
- Bellman Ford
- Dijkstra
- Johnson
- Floyd-Warshall
2. Design your own Recursive Algorithm
- Brute Force
- Decrease and Conquer
- Divide and Conquer
- Dynamic Programming
- Greedy/ Incremental
Download and/or contribute this code on GitHub
Provides the list of the opensource Flutter apps collection with GitHub repository.