Remember, this project is for helping beginners to get started with Data Structues and Algorithms
3 | and providing them resources in case they get stuck while writing some code. Please, document every line
4 | carefully such that a beginner can understand the code you have written. Refrain form using higher
5 | level language utilities and libraries as that can easily frighten or discourage a beginner.
6 |
Follow the following steps to start contributing to the codebase:
7 |
8 |
fork me.
9 |
clone my fork.
10 |
create new branch.
11 |
add code.
12 |
open new pull request.
13 |
i will approve your pull request so don't worry.
14 |
15 |
Even a small documentation would be highly appreciated.
16 |
Reach me out at: tirthasheshpatel@gmail.com
17 |
Any help would be greatly appreciated!
18 | Thank you!
19 |
--------------------------------------------------------------------------------
/Dynamic Programming/make_change_problem.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Problem statement: You have a sequence of n coins
3 | * where a_0 = 1 and a_0 < a_1 < a_2 < ... < a_n.
4 | * You have to find the minimum number of coins required to make
5 | * a change of `m` coins.
6 | * Assume each coin can be used infinitely many times.
7 | * Solution: MC(n) = min( MC(n-a_0), MC(n-a_1) ,... MC(n-a_n) ) + 1.
8 | */
9 |
10 |
11 | #include
12 | #include
13 |
14 | using namespace std;
15 |
16 | #define int long long
17 |
18 | int arr[100001], dp[100001];
19 |
20 | signed main()
21 | {
22 | int n;
23 | cin >> n;
24 | for(int i=0;i> arr[i];
25 | int m;
26 | cin >> m;
27 | for(int i=1;i<=m;i++) {
28 | int __min = LLONG_MAX;
29 | for(int j=0;ji) continue;
31 | __min = min(__min, dp[i-arr[j]]+1);
32 | }
33 | dp[i] = __min;
34 | }
35 | cout << dp[m] << endl;
36 | }
--------------------------------------------------------------------------------
/Graph Algorithms/topological_sort.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(){
4 | int i,j,k,n,a[10][10],indeg[10],flag[10],count=0;
5 |
6 | printf("Enter the no of vertices:\n");
7 | scanf("%d",&n);
8 |
9 | printf("Enter the adjacency matrix:\n");
10 | for(i=0;i
2 | #include
3 |
4 | int max_element(int arr[], int n)
5 | {
6 | int max_index=0;
7 | for(int i=0;iarr[max_index]) max_index=i;
8 | return max_index;
9 | }
10 |
11 | void counting_sort(int arr[], int aux[], int n)
12 | {
13 | // Step 1: Count the frequency of each digit.
14 | int max_index = max_element(arr, n);
15 | int freq_arr_size = arr[max_index]+1;
16 | int *freq = (int*)calloc(freq_arr_size, sizeof(int));
17 | for(int i=0;i
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/sorting_algorithms/heap_sort.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void swap(int* a, int* b)
5 | {
6 | int temp = *a;
7 | *a = *b;
8 | *b = temp;
9 | }
10 |
11 | int left(int i){ return 2*i+1; }
12 | int right(int i){ return 2*i+2; }
13 | int parent(int i){ return i/2; } // Not used
14 |
15 | void max_heapify(int arr[], int i, int n)
16 | {
17 | int largest = i;
18 | int right_child = right(i);
19 | int left_child = left(i);
20 | if(right_childarr[largest]) largest = right_child;
21 | if(left_childarr[largest]) largest = left_child;
22 | if(largest!=i) {
23 | swap(&arr[largest], &arr[i]);
24 | max_heapify(arr, largest, n);
25 | }
26 | }
27 |
28 | void create_max_heap(int arr[], int n)
29 | {
30 | for(int i=n/2-1;i>=0;i--) max_heapify(arr, i, n);
31 | }
32 |
33 | void heap_sort(int arr[], int n)
34 | {
35 | create_max_heap(arr, n);
36 | while(n)
37 | {
38 | swap(&arr[0], &arr[--n]);
39 | max_heapify(arr, 0, n);
40 | }
41 | }
42 |
43 | int main(int argc, char **argv)
44 | {
45 | int arr[10] = {1124,1233,4325,452,1231,5674,4433,2085,8890,9101};
46 | heap_sort(arr, 10);
47 | for(int i=0;i<10;i++) printf("%d ", arr[i]);
48 |
49 | return 0;
50 | }
--------------------------------------------------------------------------------
/prefix_to_infix/prefix_to_infix.cbp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/postfix_to_prefix/prefix_to_infix/prefix_to_infix.cbp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/sorting_algorithms/merge_sort.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void swap(int* a, int* b)
5 | {
6 | int temp = *a;
7 | *a = *b;
8 | *b = temp;
9 | }
10 |
11 | void merge(int arr[], int left, int mid, int right)
12 | {
13 | int left_size = mid-left+1;
14 | int right_size = right-mid;
15 | int arr_left[left_size], arr_right[right_size];
16 |
17 | for(int i=left;i<=mid;i++) arr_left[i-left] = arr[i];
18 | for(int i=mid+1;i<=right;i++) arr_right[i-mid-1] = arr[i];
19 |
20 | int i=left, j=0, k=0;
21 | while(j
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/prefix_to_postfix/prefix_to_postfix.cbp:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/sorting_algorithms/radix_sort.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int max_element(int arr[], int n)
6 | {
7 | int max_index=0;
8 | for(int i=0;iarr[max_index]) max_index=i;
9 | return max_index;
10 | }
11 |
12 | void _counting_sort_for_radix_sort(int arr[], int digit, int n)
13 | {
14 | int aux[n];
15 | int freq[10] = {0};
16 | for(int i=0;i
10 | #include
11 |
12 | // We take as arguments: `n` -> The integer representing the term
13 | // of the fibonacci sequence we want.
14 | // `memo` -> A array storing the already appeared
15 | // fibonacci term.
16 | int fibo(int n, int memo[])
17 | {
18 | // If we have already came up with
19 | // the n'th fibonacci term return it.
20 | if(memo[n] != 0) return memo[n];
21 | // Otherwise, if n is 0 or 1 then return 1.
22 | else if(n == 0 || n == 1) return 1;
23 | // Otherwise, get the result and store it in the memory.
24 | int result = fibo(n-1, memo) + fibo(n-2, memo);
25 | memo[n] = result; // store result at index `n`
26 | return result; // return the result.
27 | }
28 |
29 | int fibo_bottom_up(int n)
30 | {
31 | if(n == 0 || n == 1) return 1;
32 | int memo[n+1];
33 | memo[0] = 0;
34 | memo[1] = 1;
35 | for(int i=2;i<=n;i++)
36 | {
37 | memo[i] = memo[i-1] + memo[i-2];
38 | }
39 | return memo[n];
40 | }
41 |
42 | int main()
43 | {
44 | int memo[11] = {0};
45 | printf("%d\n", fibo(10, memo));
46 | printf("%d\n", fibo_bottom_up(11));
47 | }
--------------------------------------------------------------------------------
/Greedy Algorithms/activity_selection_problem.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | void recursive_activity_selector(int (*set)[2], int a[], int i, int n, int k)
5 | {
6 | int m = k+1;
7 | while(m < n && set[m][0] < set[k][1])
8 | {
9 | m++;
10 | }
11 | if(m
8 | #include
9 | #define int long long
10 | #define INF LLONG_MAX
11 | #define NEG_INF LLONG_MIN
12 | #define SIZE 100001
13 | using namespace std;
14 |
15 | int lwh[SIZE][3], dp_h[SIZE], used[SIZE];
16 |
17 | signed main()
18 | {
19 | int n, dp_l[SIZE]={INF}, dp_w[SIZE] = {INF};
20 | cin >> n;
21 | for(int i=0;i> l >> w >> h;
24 | lwh[i][0] = l;
25 | lwh[i][1] = w;
26 | lwh[i][2] = h;
27 | }
28 |
29 | for(int i=1;i<=n;i++) {
30 | int __max = NEG_INF;
31 | int temp, ll=dp_l[i-1], ww=dp_w[i-1];
32 | int prev_j = 0;
33 | for(int j=0;j__max&&!used[j]&&lwh[j][0]
3 | using namespace std;
4 |
5 | /* Link list node */
6 | struct Node {
7 | int data;
8 | struct Node* next;
9 | };
10 |
11 | void push(struct Node** head_ref, int new_data)
12 | {
13 | /* allocate node */
14 | struct Node* new_node = new Node;
15 |
16 | /* put in the data */
17 | new_node->data = new_data;
18 |
19 | /* link the old list off the new node */
20 | new_node->next = (*head_ref);
21 |
22 | /* move the head to point to the new node */
23 | (*head_ref) = new_node;
24 | }
25 |
26 | // Returns true if there is a loop in linked list
27 | // else returns false.
28 | bool detectLoop(struct Node* h)
29 | {
30 | unordered_set s;
31 | while (h != NULL) {
32 | // If this node is already present
33 | // in hashmap it means there is a cycle
34 | // (Because you we encountering the
35 | // node for the second time).
36 | if (s.find(h) != s.end())
37 | return true;
38 |
39 | // If we are seeing the node for
40 | // the first time, insert it in hash
41 | s.insert(h);
42 |
43 | h = h->next;
44 | }
45 |
46 | return false;
47 | }
48 |
49 | /* Drier program to test above function*/
50 | int main()
51 | {
52 | /* Start with the empty list */
53 | struct Node* head = NULL;
54 |
55 | push(&head, 20);
56 | push(&head, 4);
57 | push(&head, 15);
58 | push(&head, 10);
59 |
60 | /* Create a loop for testing */
61 | head->next->next->next->next = head;
62 |
63 | if (detectLoop(head))
64 | cout << "Loop found";
65 | else
66 | cout << "No Loop";
67 |
68 | return 0;
69 | }
70 |
71 |
--------------------------------------------------------------------------------
/Dynamic Programming/matrix_chain_multiplication.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | void print_param_of_matrix_chain(int (*s)[6],int i, int j, int n)
6 | {
7 | if(i == j) printf(" A[%d] ", i+1);
8 | else{
9 | printf("( ");
10 | print_param_of_matrix_chain(s, i, s[i][j], n);
11 | print_param_of_matrix_chain(s, s[i][j]+1, j, n);
12 | printf(" )");
13 | }
14 | }
15 |
16 | void matrix_chain_multiplication(int (*shape)[2], int n)
17 | {
18 | int nb_mul[n][n],div[n][n],temp=0;
19 | for(int i=0;i
2 | #include
3 | #include
4 |
5 | void LCS(char X[], char Y[])
6 | {
7 | int m = strlen(X)+1;
8 | int n = strlen(Y)+1;
9 | int c[m][n];
10 | char b[m][n];
11 | for(int i=0;i= c[i][j-1])
23 | {
24 | c[i][j] = c[i-1][j];
25 | b[i][j] = '|';
26 | }
27 | else
28 | {
29 | c[i][j] = c[i][j-1];
30 | b[i][j] = '-';
31 | }
32 | }
33 | }
34 | printf("\n");
35 | printf(" - ");
36 | for(int i=0;i= c[i][j-1])
67 | {
68 | i--;
69 | }
70 | else j--;
71 | }
72 | lcs[c[m-1][n-1]] = '\0';
73 | printf("The lcs of %s and %s is %s.", X, Y, lcs);
74 | }
75 |
76 | int main()
77 | {
78 | char A[] = "tirthasheshpatel";
79 | char B[] = "letaphsehsahtrit";
80 | LCS(A,B);
81 | }
82 |
--------------------------------------------------------------------------------
/direct_address_table.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define MAX 10000
6 |
7 |
8 | typedef size_t size_type;
9 | typedef struct Table* iterator;
10 | typedef const struct Table* const_iterator;
11 |
12 | struct Table
13 | {
14 | int key;
15 | char element[100];
16 | };
17 |
18 | int insert_in_dat(iterator t, int key, char element[])
19 | {
20 | if(key < 0 || key >= MAX) return 1;
21 | else if(t[key].key != -1) return 2;
22 | struct Table temp = {key, element};
23 | t[key] = temp;
24 | return 0;
25 | }
26 |
27 | int del_from_dat(iterator t, int key)
28 | {
29 | if(key < 0 || key >= MAX) return 1;
30 | t[key].key = -1;
31 | strcpy(t[key].element, "");
32 | return 0;
33 | }
34 |
35 | int search_in_dat(iterator t, int key)
36 | {
37 | if(key < 0 || key >= MAX) return 0;
38 | else if(t[key].key == -1) return 0;
39 | return 1;
40 | }
41 |
42 | int main()
43 | {
44 | iterator slots = (iterator)malloc(MAX*sizeof(struct Table));
45 | for(int i=0;i
2 | #include
3 | #include "boilerplate.h"
4 |
5 | #define print printf
6 | #define scan scanf
7 |
8 | void BFS(vertex_iterator source)
9 | {
10 | Queue* q = (Queue*)malloc(sizeof(Queue));
11 | initalize_queue(q, 10);
12 | source->color = 'G';
13 | source->depth = 0;
14 | source->parent = 0;
15 | enqueue(q, source);
16 | while(q->front != -1)
17 | {
18 | vertex_iterator u = dequeue(q);
19 | list_iterator temp = u->adj_list;
20 | while(temp != 0)
21 | {
22 | if(temp->key->color == 'W')
23 | {
24 | // print("New vertex found at %x!\n", temp->key);
25 | temp->key->color = 'G';
26 | temp->key->depth = u->depth + 1;
27 | temp->key->parent = u;
28 | enqueue(q, temp->key);
29 | }
30 | temp = temp->next;
31 | }
32 | u->color = 'B';
33 | print("Node with value %d fount at depth %d\n", u->value, u->depth);
34 | }
35 | }
36 |
37 | int main(int argc, char *argv[])
38 | {
39 | int nb_vertices;
40 | print("Enter the number of vertices in your graph: ");
41 | scan("%d", &nb_vertices);
42 |
43 | vertex_iterator* graph = (vertex_iterator*)malloc(nb_vertices*sizeof(vertex_iterator));
44 |
45 | print("Enter value of all the vertices: ");
46 | fflush(stdin);
47 | for(int i=0;ivalue = temp;
53 | graph[i]->color = 'W';
54 | graph[i]->depth = -1;
55 | graph[i]->parent = 0;
56 | graph[i]->adj_list = 0;
57 | graph[i]->end = -1;
58 | graph[i]->start = -1;
59 | // print("Vertex added to graph\n");
60 | }
61 |
62 | print("Enter the index of nodes in the adjecent list of vertex with value \n");
63 | for(int i=0;ivalue);
68 | while(ind!=-1)
69 | {
70 | scan("%d", &ind);
71 | if(ind == -1) break;
72 |
73 | if(templ==0) templ = create_doubly_linked_list(graph[ind]);
74 | else templ = insert_in_front_of_the_doubly_linked_list(templ, graph[ind]);
75 | }
76 | graph[i]->adj_list = templ;
77 | fflush(stdin);
78 | }
79 | int index;
80 | print("Enter the source to run BFS on: ");
81 | scan("%d", &index);
82 | print("\n\n");
83 | BFS(graph[index]);
84 | }
--------------------------------------------------------------------------------
/Dynamic Programming/rod_cutting_problem.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #define max(a,b) (((a) > (b)) ? (a) : (b))
7 |
8 | typedef struct pair
9 | {
10 | int x;
11 | int y;
12 | }Pair;
13 |
14 | int callbacks = 0;
15 |
16 | int cut_rod_top_down(int n, int rev[])
17 | {
18 | callbacks++;
19 | if(n == 0) return 0;
20 | int r = INT_MIN;
21 | for(int i=0;i
8 | #include
9 |
10 |
11 | struct queue
12 | {
13 | int size;
14 | int front;
15 | int rear;
16 | int *que;
17 | };
18 |
19 |
20 | void insert(struct queue *q,int val)
21 | {
22 | if(q->front==(q->rear+1)%q->size)
23 | printf("\nQueue Overflow!");
24 | else
25 | {
26 | q->rear=(q->rear+1)%q->size;
27 | q->que[q->rear]=val;
28 | if(q->front==-1)
29 | q->front=0;
30 | }
31 | }
32 |
33 |
34 | int delete(struct queue *q)
35 | {
36 | if(q->front==-1)
37 | {
38 | printf("\nQueue Underflow!");
39 | exit(1);
40 | }
41 |
42 | else
43 | {
44 | int ele;
45 | ele=q->que[q->front];
46 | if(q->front==q->rear)
47 | {
48 | q->front=-1;
49 | q->rear=-1;
50 | }
51 | else
52 | q->front=(q->front+1)%q->size;
53 | return ele;
54 | }
55 | }
56 |
57 |
58 | void display(struct queue *q)
59 | {
60 | printf("\nThe elements in queue are ");
61 | if(q->rear >= q->front){
62 | for(int i=q->front;i<=q->rear;i++)
63 | {
64 | printf("%d ",q->que[i]);
65 | }
66 | }
67 | else
68 | {
69 | for(int i=q->front;isize || i%q->size<=q->rear;i++)
70 | {
71 | printf("%d ",q->que[i%q->size]);
72 | }
73 | }
74 | }
75 |
76 |
77 | int main()
78 | {
79 | struct queue q;
80 | q.front=-1;
81 | q.rear=-1;
82 | printf("\nEnter the size of queue: ");
83 | scanf("%d",&q.size);
84 | q.que=(int *) malloc(q.size*sizeof(int));
85 | int val,ch;
86 | do
87 | {
88 | printf("\n1. Insert \n2. Delete \n3. Display \n4. Quit");
89 | printf("\nEnter your choice: ");
90 | scanf("%d",&ch);
91 | getchar();
92 | switch(ch)
93 | {
94 | case 1: printf("\nEnter the value to insert: ");
95 | scanf("%d",&val);
96 | insert(&q,val);
97 | break;
98 | case 2: val=delete(&q);
99 | printf("\nDeleted element is %d",val);
100 | break;
101 | case 3: display(&q);
102 | break;
103 | case 4: ch=4;
104 | break;
105 | default: printf("\nEnter a valid choice!");
106 | break;
107 | }
108 | } while (ch!=4);
109 | }
--------------------------------------------------------------------------------
/cpp_algorithms/queue_in_cpp/queue/Queue.h:
--------------------------------------------------------------------------------
1 | #ifndef GUARD_QUEUE_H
2 | #define GUARD_QUEUE_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | using std::max;
9 |
10 | template
11 | class Queue
12 | {
13 | public:
14 | typedef T* iterator;
15 | typedef const T* const_iterator;
16 | typedef size_t size_type;
17 | typedef T value_type;
18 |
19 | Queue() { create(); }
20 | explicit Queue(size_type n, const T& val = T()) { create(n, val); }
21 | Queue(const Queue& q) { create(q.begin(), q.end()); }
22 | Queue& operator=(const Queue&);
23 | ~Queue() { uncreate(); }
24 |
25 | T& operator[](size_type i) { return data[i]; }
26 | const T& operator[](size_type i) const { return data[i]; }
27 |
28 | size_type size() const { return avail - data; }
29 | void empty() { return avail == data; }
30 | void clear() { uncreate(); }
31 |
32 | T& dequeue() {
33 | if (data) {
34 | T val = data[0];
35 | size_type new_size = max(limit - data, ptrdiff_t(1));
36 | iterator new_data = alloc.allocate(new_size);
37 | iterator new_avail = std::uninitialized_copy(data + 1, avail, new_data);
38 | uncreate();
39 | data = new_data;
40 | avail = new_avail;
41 | limit = data + new_size;
42 | return val;
43 | }
44 | else throw std::domain_error("Queue Underflow!");
45 | }
46 | void enqueue(const T& val) {
47 | if (avail == limit) grow();
48 | append(val);
49 | }
50 |
51 |
52 | private:
53 | iterator data;
54 | iterator avail;
55 | iterator limit;
56 | std::allocator alloc;
57 |
58 | void create() {
59 | data = avail = limit = 0;
60 | }
61 | void create(size_type n, const T& val) {
62 | data = alloc.allocate(n);
63 | avail = limit = data + n;
64 | std::uninitialized_fill(data, avail, val);
65 | }
66 | void create(const_iterator i, const_iterator j) {
67 | data = alloc.allocate(j - i);
68 | avail = limit = std::uninitialized_copy(i, j, data);
69 | }
70 |
71 | void uncreate() {
72 | if (data) {
73 | iterator it = avail;
74 | while (it != avail) {
75 | alloc.destroy(--it);
76 | }
77 | alloc.deallocate(data, limit - data);
78 | }
79 | data = avail = limit = 0;
80 | }
81 |
82 | void grow() {
83 | size_type new_size = max(2 * (avail - data), ptrdiff_t(1));
84 | iterator new_data = alloc.allocate(new_size);
85 | iterator new_avail = std::uninitialized_copy(data, avail, new_data);
86 | uncreate();
87 | data = new_data;
88 | avail = new_avail;
89 | limit = new_data + new_size;
90 | }
91 |
92 | void append(const T& val) {
93 | alloc.construct(avail++, val);
94 | }
95 | };
96 |
97 | #endif
98 |
99 | template
100 | Queue& Queue::operator=(const Queue& rhs)
101 | {
102 | if (&rhs != this) {
103 | uncreate();
104 |
105 | create(rhs.begin(), rhs.end());
106 | }
107 | return *this;
108 | }
109 |
--------------------------------------------------------------------------------
/partition_allocation.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | int search(int size, int partitions[], int n_partitions, const char method)
7 | {
8 | int index = INT_MAX;
9 | if(method == 'f') {
10 | for(int i=0;i=size) {
12 | return i;
13 | }
14 | }
15 | }
16 | else if(method == 'n') {
17 | for(int i=n_partitions-1;i>=0;i--) {
18 | if(partitions[i]>=size) {
19 | return i;
20 | }
21 | }
22 | }
23 | else if(method == 'b') {
24 | int min_req = INT_MAX, min_ind = INT_MAX;
25 | for(int i=0;i=size && partitions[i]=size && partitions[i]>max_req) {
37 | max_req = partitions[i];
38 | max_ind = i;
39 | }
40 | }
41 | return max_ind;
42 | }
43 | else {
44 | printf("method %c not found.\n", method);
45 | }
46 | return index;
47 | }
48 |
49 | bool allocate_process(int processes[], int n_processes, int partitions[], int n_partitions, const char method)
50 | {
51 | int **allocated_processes;
52 | allocated_processes = (int**)calloc(n_processes, sizeof(int*));
53 | for(int process=0;processn_partitions) {
58 | printf("unable to allocate process %d.\n", process);
59 | printf("size of process: %d.\n", size);
60 | printf("available sizes of partitions: ");
61 | for(int i=0;i
5 | #include
6 | #include
7 | #include
8 |
9 | template
10 | class Stack
11 | {
12 | public:
13 | typedef T* iterator;
14 | typedef const T* const_iterator;
15 | typedef size_t size_type;
16 | typedef T value_type;
17 |
18 | Stack() { create(); }
19 | explicit Stack(size_type n, const T& val = T()) { create(n, val); }
20 | Stack(const Stack& s) { create(s.begin(), s.end()); }
21 | Stack& operator=(const Stack&);
22 | ~Stack() { uncreate(); }
23 |
24 | size_type size() const { return avail - data; }
25 |
26 | T& operator[](size_type i) { return data[i]; }
27 | const T& operator[](size_type i) const { return data[i]; }
28 |
29 | iterator begin() { return data; }
30 | const_iterator begin() const { return data; }
31 |
32 | iterator end() { return avail; }
33 | const_iterator end() const { return avail; }
34 |
35 | T& pop_back();
36 | void push_back(const T&);
37 | void clear() { uncreate(); }
38 | bool empty() { return data == avail; }
39 |
40 |
41 | private:
42 | iterator data;
43 | iterator avail;
44 | iterator limit;
45 | std::allocator alloc;
46 |
47 | void create();
48 | void create(size_type, const T&);
49 | void create(const_iterator, const_iterator);
50 | void grow();
51 | void uncreate();
52 | void append(const T&);
53 |
54 | };
55 |
56 | #endif
57 |
58 | template
59 | T& Stack::pop_back()
60 | {
61 | if (avail == data) { throw std::domain_error("Stack Underflow!"); }
62 | iterator it = avail;
63 | T val = *(it - 1);
64 | alloc.destroy(--it);
65 | avail--;
66 | return val;
67 | }
68 |
69 | template
70 | void Stack::push_back(const T& val)
71 | {
72 | if (avail == limit) grow();
73 | append(val);
74 | }
75 |
76 | template
77 | void Stack::create()
78 | {
79 | data = avail = limit = 0;
80 | }
81 |
82 | template
83 | void Stack::create(size_type n, const T& val)
84 | {
85 | data = alloc.allocate(n);
86 | limit = avail = data + n;
87 | std::uninitialized_fill(data, avail, val);
88 | }
89 |
90 | template
91 | void Stack::create(const_iterator i, const_iterator j)
92 | {
93 | data = alloc.allocate(j - i);
94 | avail = limit = std::uninitialized_copy(i, j, data);
95 | }
96 |
97 | template
98 | void Stack::grow()
99 | {
100 | size_type new_size = std::max(2 * (limit - data), ptrdiff_t(1));
101 | iterator new_data = alloc.allocate(new_size);
102 | iterator new_avail = std::uninitialized_copy(data, avail, new_data);
103 |
104 | uncreate();
105 |
106 | data = new_data;
107 | avail = new_avail;
108 | limit = data + new_size;
109 | }
110 |
111 | template
112 | void Stack::uncreate()
113 | {
114 | if (data) {
115 | iterator it = avail;
116 | while (it != data) {
117 | alloc.destroy(--it);
118 | }
119 | alloc.deallocate(data, limit - data);
120 | }
121 | data = avail = limit = 0;
122 | }
123 |
124 | template
125 | void Stack::append(const T& val)
126 | {
127 | alloc.construct(avail++, val);
128 | }
129 |
130 | template
131 | Stack& Stack::operator=(const Stack& rhs)
132 | {
133 | if (&rhs != this) {
134 | uncreate();
135 |
136 | create(rhs.begin(), rhs.end());
137 | }
138 | return *this;
139 | }
140 |
141 |
--------------------------------------------------------------------------------
/Graph Algorithms/depth_first_search.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include "boilerplate.h"
4 |
5 | #define print printf
6 | #define scan scanf
7 |
8 | void DFS(vertex_iterator* graph, int nb_vertices, vertex_iterator source)
9 | {
10 | // graph = 1->2->3->4->5, source = 1
11 | int currTime = 0, explored = 0;
12 | Stack* s = (Stack*)malloc(sizeof(Stack));
13 | init_stack(s);
14 | while(1)
15 | {
16 | push(s, source);
17 | source->color = 'G';
18 | source->start = ++currTime;
19 | while(s->empty != 1)
20 | {
21 | vertex_iterator v = pop(s);
22 | if(v->color == 'B')
23 | {
24 | v->end = ++currTime;
25 | print("Node with value %d fount at time %d and its exploration ended at time %d\n", v->value, v->start, v->end);
26 | }
27 | else push(s, v);
28 | list_iterator temp = v->adj_list;
29 | while(temp != 0)
30 | {
31 | if(temp->key->color == 'W')
32 | {
33 | temp->key->start = ++currTime;
34 | temp->key->parent = v;
35 | temp->key->color = 'G';
36 | push(s, temp->key);
37 | }
38 | temp = temp->next;
39 | }
40 | v->color = 'B';
41 | }
42 |
43 | explored = 1;
44 | for(int i=0;icolor == 'W')
47 | {
48 | source = graph[i];
49 | explored = 0;
50 | break;
51 | }
52 | }
53 |
54 | if(explored == 0) continue;
55 | free(s);
56 | break;
57 | }
58 | }
59 |
60 | int main(int argc, int argv[])
61 | {
62 | int nb_vertices;
63 | print("Enter the number of vertices in your graph: ");
64 | scan("%d", &nb_vertices);
65 |
66 | vertex_iterator* graph = (vertex_iterator*)malloc(nb_vertices*sizeof(vertex_iterator));
67 |
68 | print("Enter value of all the vertices: ");
69 | fflush(stdin);
70 | for(int i=0;ivalue = temp;
76 | graph[i]->color = 'W';
77 | graph[i]->depth = -1;
78 | graph[i]->parent = 0;
79 | graph[i]->adj_list = 0;
80 | graph[i]->end = -1;
81 | graph[i]->start = -1;
82 | // print("Vertex added to graph\n");
83 | }
84 |
85 | print("Enter the index of nodes in the adjecent list of vertex with value \n");
86 | for(int i=0;ivalue);
91 | while(ind!=-1)
92 | {
93 | scan("%d", &ind);
94 | if(ind == -1) break;
95 |
96 | if(templ==0) templ = create_doubly_linked_list(graph[ind]);
97 | else templ = insert_in_front_of_the_doubly_linked_list(templ, graph[ind]);
98 | }
99 | graph[i]->adj_list = templ;
100 | fflush(stdin);
101 | }
102 | int index;
103 | print("Enter the source to run DFS on: ");
104 | scan("%d", &index);
105 | print("\n\n");
106 | DFS(graph, nb_vertices, graph[index]);
107 | }
--------------------------------------------------------------------------------
/stack_algorithms/stack_as_static_arrays.c:
--------------------------------------------------------------------------------
1 | #include // Handles standard input/output
2 | #include // Error Handling library
3 | #include
4 |
5 | // The maximum number of elements that can be stored in a stack.
6 | #define MAX 65535
7 |
8 | // Structure of stack
9 | struct stack
10 | {
11 | // A integer pointing at the top of the stack.
12 | int top;
13 | // A array to hold the values of stack.
14 | int arr[MAX+1];
15 | }s;
16 |
17 | // Deletes and returns the top element in a stack.
18 | int POP(struct stack* s)
19 | {
20 | // IMPLEMENT POP
21 |
22 | // Handle error when stack is empty.
23 | if(s->top == -1) perror("Stack Underflow!");
24 |
25 | // Get a copy of value at the top of the stack
26 | // in a variable `element` that we are going to return.
27 | int element = s->arr[s->top];
28 |
29 | // Initialize the value at the top of the stack again to 0.
30 | s->arr[s->top] = 0;
31 | // Decrease the value of `top` by 1.
32 | s->top--;
33 |
34 | // Finally, return `element`.
35 | return element;
36 | }
37 |
38 | // Adds a element onto the top of stack
39 | void PUSH(struct stack* s, int value)
40 | {
41 | // IMPLEMENT PUSH
42 |
43 | // Handle error in case the stack has reached its maximum limit `MAX`.
44 | if(s->top == MAX) perror("Stack Overflow!");
45 |
46 | // Increase the value of `top` by 1.
47 | s->top++;
48 | // Insert element at the index `top`.
49 | s->arr[s->top] = value;
50 | }
51 |
52 | // Returns the i'th element from the top of the stack
53 | int PEEP(struct stack* s, int index)
54 | {
55 | // IMPLEMENT PEEP
56 |
57 | // Handle error if index is not valid
58 | if(index <= 0 || index > MAX) perror("index out of range!");
59 | return s->arr[s->top - index]; // return the i'th element from the top.
60 | }
61 |
62 | void CHANGE(struct stack* s, int index, int new_value)
63 | {
64 | // IMPLEMENT CHANGE
65 |
66 | // Handle error in case of out of range access.
67 | if(index <= 0 || index > MAX) perror("index out of range!");
68 |
69 | // Insert the new value at index `top-index`.
70 | s->arr[s->top - index] = new_value;
71 |
72 | }
73 |
74 | void PRINT_STACK(struct stack* s)
75 | {
76 | if(s->top == -1) perror("Nothing present in stack!");
77 | for(int i=0;i<=s->top;i++){
78 | printf("%d ", PEEP(s, s->top-i));
79 | }
80 | printf("\n");
81 | }
82 |
83 |
84 | int main()
85 | {
86 | struct stack s = {-1, 0};
87 | char command;
88 | while(1)
89 | {
90 | printf("Enter command: ");
91 | scanf("%c", &command);
92 | fflush(stdout);
93 | fflush(stdin);
94 | if(command == 'i'){
95 | printf("Enter the value to insert: ");
96 | int value;
97 | scanf("%d", &value);
98 | PUSH(&s, value);
99 | }
100 | else if(command == 'd'){
101 | int deleted_element = POP(&s);
102 | printf("The element popped is: %d", deleted_element);
103 | }
104 | else if(command == 'p'){
105 | printf("Enter the index at which you wnat to peep: ");
106 | int index;
107 | scanf("%d", &index);
108 | int peeped_element = PEEP(&s, index);
109 | printf("Peeped Element: ", peeped_element);
110 | }
111 | else if(command == 'c'){
112 | printf("Enter the index you wnat to edit: ");
113 | int index;
114 | scanf("%d", &index);
115 | printf("Enter the new value: ");
116 | int new_value;
117 | scanf("%d", &new_value);
118 | CHANGE(&s, index, new_value);
119 | }
120 | else if(command == 's') PRINT_STACK(&s);
121 | else if(command == 'q') break;
122 | else perror("Command not found!");
123 |
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/queue_algorithms/queue_using_static_array.c:
--------------------------------------------------------------------------------
1 | /*
2 | * @author: tirthasheshpatel
3 | * @g-mail: tirthasheshpatel@gmail.com
4 | * Summary: Queue implemented using static array
5 | */
6 |
7 | // Inclusing necessary libraries
8 | #include // printf, scanf, fflush
9 | #include
10 |
11 | #define MAX 65535
12 |
13 | // Alternate for `struct queue`
14 | typedef struct queue Queue;
15 | // Alternate for `size_t`
16 | typedef size_t size_type;
17 |
18 | // A stucture for Queue holding attributes:
19 | // `front`: A integer indicating the first element in the array
20 | // `rear` : A integer indicating the last element in the array.
21 | // `q` : A array (of size `MAX`) holding values in the queue.
22 | struct queue
23 | {
24 | int front;
25 | int rear;
26 | int q[MAX+1];
27 | };
28 |
29 | // Deletes a element from the front of the Queue.
30 | int dequeue(Queue* q)
31 | {
32 | /*
33 | * Arguments: `q` (Queue*) -> A referance to a Queue object
34 | * Deletes and returns the first element present in the Queue `q`.
35 | * Returns : `ele` (int) -> First element in the Queue `q`
36 | */
37 |
38 | // If the `front` and `rear` attributes of
39 | // Queue `q` are overlapping
40 | // and are not equal to -1 means there is
41 | // only one element present in the Queue
42 | // which we will delete and reset the attributes
43 | // again to -1.
44 | if(q->front == q->rear && q->front != -1)
45 | {
46 | int ele = q->q[q->front]; // get element in front of the queue
47 | q->q[q->front] = 0; // reinitialize the element
48 | q->front = q->rear = -1; // reset the attributes
49 | return ele; // return element.
50 | }
51 |
52 | // If the front or the rear attributes
53 | // are -1 means there are no elements
54 | // present in the queue and further
55 | // deletion doesn't make sense. So,
56 | // print error.
57 | else if(q->front == -1)
58 | {
59 | printf("Queue Underflow!\nTerminating Program...\n");
60 | exit(1); // terminate program
61 | }
62 |
63 | // Else delete element and increament
64 | // `front` attribute of Queue `q`.
65 | else
66 | {
67 | // extract the element
68 | int ele = q->q[q->front];
69 | q->q[q->front] = 0; // reinitialize the element
70 | q->front++; // increment front
71 | return ele; // return element
72 | }
73 | }
74 |
75 | void enqueue(Queue* q, int key)
76 | {
77 | /*
78 | * Arguments: `q` (Queue*) -> A referance to a queue `q`.
79 | * `key` (int) -> A value to be inserted in the queue `q`.
80 | * Inserts `key` at the top of the queue `q`.
81 | */
82 |
83 | // If the rear of the queue has reached its
84 | // maximum `MAX` print error Overflow.
85 | if(q->rear == MAX){
86 | printf("Queue Overflow\nTerminating Program...\n");
87 | exit(1);
88 | }
89 |
90 | // Else insert key at the end of
91 | // the queue `q`.
92 | else
93 | {
94 | q->rear++; // increment attribute `rear`
95 | q->q[q->rear] = key; // insert key
96 | // If this is the first element inserted
97 | // in the Queue, do q->front = 0;
98 | if(q->front == -1) q->front++;
99 | }
100 | }
101 |
102 | void disp_queue(Queue* q)
103 | {
104 | if(q->front == -1) printf("No elements present in the queue!");
105 | else for(int i=q->front;i<=q->rear;i++) printf("%d ", q->q[i]);
106 | printf("\n");
107 | }
108 |
109 | int main()
110 | {
111 | Queue que = {-1,-1,0};
112 | enqueue(&que, 10);
113 | enqueue(&que, 20);
114 | disp_queue(&que);
115 | dequeue(&que);
116 | disp_queue(&que);
117 | dequeue(&que);
118 | disp_queue(&que);
119 | }
--------------------------------------------------------------------------------
/queue_algorithms/priority_queue.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #define MAX 3
6 |
7 | typedef struct queue Queue;
8 |
9 | struct queue
10 | {
11 | int front;
12 | int rear;
13 | int q[MAX+1][2];
14 | };
15 |
16 | // Deletes a element from the front of the Queue.
17 | int* dequeue(Queue* q)
18 | {
19 | /*
20 | * Arguments: `q` (Queue*) -> A referance to a Queue object
21 | * Deletes and returns the first element present in the Queue `q`.
22 | * Returns : `ele` (int) -> First element in the Queue `q`
23 | */
24 |
25 | // If the `front` and `rear` attributes of
26 | // Queue `q` are overlapping
27 | // and are not equal to -1 means there is
28 | // only one element present in the Queue
29 | // which we will delete and reset the attributes
30 | // again to -1.
31 | if(q->front == q->rear && q->front != -1)
32 | {
33 | int *ele = q->q[q->front]; // get element in front of the queue
34 | q->q[q->front][0] = 0; // reinitialize the element
35 | q->q[q->front][1] = 0; // reinitialize priority
36 | q->front = q->rear = -1; // reset the attributes
37 | return ele; // return element.
38 | }
39 |
40 | // If the front or the rear attributes
41 | // are -1 means there are no elements
42 | // present in the queue and further
43 | // deletion doesn't make sense. So,
44 | // print error.
45 | else if(q->front == -1)
46 | {
47 | printf("Queue Underflow!\nTerminating Program...\n");
48 | exit(1); // terminate program
49 | }
50 |
51 | // Else delete element and increament
52 | // `front` attribute of Queue `q`.
53 | else
54 | {
55 | // extract the element
56 | int *ele = q->q[q->front];
57 | q->q[q->front][0] = 0; // reinitialize the element
58 | q->q[q->front][1] = 0; // reinitialize priority
59 | q->front++; // increment front
60 | return ele; // return element
61 | }
62 | }
63 |
64 | void enqueue(Queue* q, int key, int priority)
65 | {
66 | /*
67 | * Arguments: `q` (Queue*) -> A referance to a queue `q`.
68 | * `key` (int) -> A value to be inserted in the queue `q`.
69 | * Inserts `key` at the top of the queue `q`.
70 | */
71 |
72 | // If the rear of the queue has reached its
73 | // maximum `MAX` print error Overflow.
74 | if(q->rear == MAX){
75 | printf("Queue Overflow\nTerminating Program...\n");
76 | exit(1);
77 | }
78 |
79 | // Else insert key at the end of
80 | // the queue `q`.
81 | else
82 | {
83 | if(q->rear!=-1){
84 | int insertInd = q->rear;
85 | q->rear++; // increment attribute `rear`
86 | while(priority < q->q[insertInd][1])
87 | {
88 | q->q[insertInd+1][0] = q->q[insertInd][0];
89 | q->q[insertInd+1][1] = q->q[insertInd][1];
90 | insertInd--;
91 | }
92 | q->q[insertInd+1][0] = key; // insert key
93 | q->q[insertInd+1][1] = priority; // insert priority
94 | }
95 | else
96 | {
97 | q->rear++;
98 | q->q[q->rear][0] = key; // insert key
99 | q->q[q->rear][1] = priority; // insert priority
100 | q->front++;
101 | }
102 |
103 | }
104 | }
105 |
106 | void disp_queue(Queue* q)
107 | {
108 | if(q->front == -1) printf("No elements present in the queue!");
109 | else for(int i=q->front;i<=q->rear;i++) printf("[%d]%d ", q->q[i][1], q->q[i][0]);
110 | printf("\n");
111 | }
112 |
113 | void init_queue(Queue* q)
114 | {
115 | q->front = -1;
116 | q->rear = -1;
117 | for(int i=0;iq[i][0] = q->q[i][1] = 0;
120 | }
121 | }
122 |
123 | int main()
124 | {
125 | Queue que;
126 | init_queue(&que);
127 | enqueue(&que, 10, 1);
128 | enqueue(&que, 20, 2);
129 | enqueue(&que, 30, 3);
130 | enqueue(&que, 40, 1);
131 | disp_queue(&que);
132 | }
--------------------------------------------------------------------------------
/linked_list_algorithms/singly_linked_list.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | typedef struct node Node;
4 | typedef struct node* list_iterator;
5 |
6 | struct node
7 | {
8 | int key;
9 | list_iterator next;
10 | };
11 |
12 | list_iterator create_singly_linked_list(int key)
13 | {
14 | list_iterator first = (list_iterator)malloc(sizeof(Node));
15 | first->key = key;
16 | first->next = 0;
17 | return first;
18 | }
19 |
20 | list_iterator insert_after_in_singly_linked_list(int key, int prev_key, list_iterator first)
21 | {
22 | list_iterator it = first;
23 | while(it->key != prev_key)
24 | {
25 | if(it->next == 0)
26 | {
27 | printf("Key not found!\n");
28 | return first;
29 | }
30 | it = it->next;
31 | }
32 | list_iterator new_node = (list_iterator)malloc(sizeof(Node));
33 | new_node->key = key;
34 | new_node->next = it->next;
35 | it->next = new_node;
36 | return first;
37 | }
38 |
39 | list_iterator insert_in_front_of_singly_linked_list(int key, list_iterator first)
40 | {
41 | list_iterator new_node = (list_iterator)malloc(sizeof(Node));
42 | new_node->key = key;
43 | new_node->next = first;
44 | first->next = new_node;
45 | return first;
46 | }
47 |
48 | list_iterator insert_in_end_of_singly_linked_list(int key, list_iterator first)
49 | {
50 | list_iterator it = first;
51 | while(it->next != 0)
52 | {
53 | it = it->next;
54 | }
55 | list_iterator new_node = (list_iterator)malloc(sizeof(Node));
56 | new_node->key = key;
57 | new_node->next = NULL;
58 | it->next = new_node;
59 | return first;
60 | }
61 |
62 | list_iterator insert_before_in_singly_linked_list(int key, int prev_key, list_iterator first)
63 | {
64 | list_iterator it = first;
65 | list_iterator prev= 0;
66 | while(it->key != prev_key)
67 | {
68 | if(it->next == 0)
69 | {
70 | printf("Key not found!\n");
71 | return first;
72 | }
73 | prev = it;
74 | it = it->next;
75 | }
76 | if(prev == 0)
77 | {
78 | first = insert_in_front_of_singly_linked_list(key, first);
79 | return first;
80 | }
81 | list_iterator new_node = (list_iterator)malloc(sizeof(Node));
82 | new_node->key = key;
83 | new_node->next = it;
84 | prev->next = new_node;
85 | return first;
86 | }
87 |
88 | list_iterator delete_from_singly_linked_list(int key, list_iterator first)
89 | {
90 | list_iterator prev = 0;
91 | list_iterator it = first;
92 | while(it->key != key)
93 | {
94 | if(it->next == 0)
95 | {
96 | printf("Key not found!\n");
97 | return first;
98 | }
99 | prev = it;
100 | it = it->next;
101 | }
102 | if(it == first)
103 | {
104 | first = first->next;
105 | free(it);
106 | return first;
107 | }
108 | prev->next = it->next;
109 | free(it);
110 | return first;
111 | }
112 |
113 | void transverse_in_singly_linked_list(list_iterator first)
114 | {
115 | if(first == 0){
116 | printf("Empty!\n");
117 | return;
118 | }
119 | list_iterator it = first;
120 | while(it->next != 0)
121 | {
122 | printf("%d -> ", it->key);
123 | it = it->next;
124 | }
125 | printf("%d\n", it->key);
126 | }
127 |
128 | int main()
129 | {
130 | list_iterator first = create_singly_linked_list(10);
131 | // 10
132 | first = insert_after_in_singly_linked_list(20, 10, first);
133 | first = insert_after_in_singly_linked_list(30, 20, first);
134 | first = insert_before_in_singly_linked_list(60, 30, first);
135 | first = insert_after_in_singly_linked_list(40, 10, first);
136 | transverse_in_singly_linked_list(first);
137 | first = delete_from_singly_linked_list(10, first);
138 | first = delete_from_singly_linked_list(30, first);
139 | transverse_in_singly_linked_list(first);
140 | first = delete_from_singly_linked_list(40, first);
141 | first = delete_from_singly_linked_list(20, first);
142 | transverse_in_singly_linked_list(first);
143 | }
144 |
--------------------------------------------------------------------------------
/postfix_to_infix/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | ->Author : Tirth Hihoriya
3 | ->Editor : Tirth Patel
4 | ->E-mail : tirth.hihoriya@gmail.com, tirthasheshpatel@gmail.com
5 | ->Summary : Converting `postfix` to `infix` using STACK
6 | */
7 | #include
8 | #include // malloc, calloc
9 | #include // isalpha
10 | #include // strlen, strcpy, strcat
11 | #include // perror
12 |
13 | // Making a Structure of Stack that can store
14 | // a string
15 | struct stack
16 | {
17 | int top; // integer indicating the size of the string array
18 | // An array of maximum 100 string type element.
19 | char st[100][100];
20 | };
21 |
22 | // PUSH is a operation
23 | // to add an element onto the stack.
24 | void PUSH(struct stack *s,char n3[])
25 | {
26 | /*
27 | * Arguments: `s` (stack) -> A stack object in which you want to push.
28 | * `n3` (c_str) -> A string object to be pushed to the stack `s`.
29 | * Inserts the string `n3` on the top of the stack.
30 | * Returns: -
31 | */
32 |
33 | // If stack is full print error "Overflow!"
34 | if(s->top==100) perror("Overflow");
35 |
36 | // Else, increment the top attribute of the stack
37 | // and insert element at the new index of the `st` attribute
38 | // of stack.
39 | else
40 | {
41 | s->top++; // increment top
42 | strcpy(s->st[s->top],n3); // Copy the passed string onto the stack.
43 | }
44 |
45 | }
46 |
47 |
48 | // POP element from the top of the stack
49 | void POP(struct stack *s, char element[])
50 | {
51 | /*
52 | * Arguments: `s` (stack) -> A stack object from which the element
53 | * is being poped.
54 | * `element` (c_str) -> A string object in which the poped element
55 | * is stored.
56 | * Deletes top element from the `st` attribute of the stack object
57 | * and stores the deleted object in string `element`.
58 | * Returns: -
59 | */
60 |
61 | // If the stack is empty, print error "Underflow"
62 | if(s->top==-1) perror("Underflow\n");
63 |
64 | // Else, copy the top string and decrement `top` attribute by 1.
65 | else{
66 | strcpy(element,s->st[s->top]); // copy top of stack in `element`
67 | s->top--; // decrement top
68 | return;
69 | }
70 | }
71 |
72 |
73 | // Converts a postfix strint to infix.
74 | void postfix_to_infix(char p[])
75 | {
76 | // Make a stack object and initialize the `top` as -1.
77 | struct stack s = {-1};
78 | int i=0; // used to iterate through the infix string.
79 | do
80 | {
81 | if(isalpha(p[i])) //isalpha(p[i]) will return true if
82 | //p[i] is alphabet i.e. for us `variable name`
83 | {
84 | char temp[100]; //it is temporary string to copy the `variable name`
85 | temp[0]=p[i];
86 | temp[1]='\0'; //because string should end with `\0`
87 | PUSH(&s,temp); //it will push the `temp` to the stack of string
88 | }
89 |
90 | // Now if while scanning the postfix if any operator aqppears then
91 | // POP the last `variable_name` then append the operator then
92 | // again POP the `variable_name` and also append it.
93 | else if(p[i]=='+' || p[i]=='-' || p[i]=='*' || p[i]=='/' || p[i]=='%') //these are some binary operator
94 | {
95 | char n3[100]; //`n3` is for the final string after appending the expresstion.
96 | strcpy(n3,"("); //initializing `n3` with `(` so that precedece is maintainted.
97 | char n2[100]; //`n2` is for the second `variable_name`
98 | POP(&s, n2);
99 | char n1[100]; //`n1` is for the first `variable_name`
100 | POP(&s, n1);
101 | strcat(n3,n1); // concatenating `n1` in `n3`.
102 | size_t sz = strlen(n3); // storing length of `n3` in `sz` variable.
103 | n3[sz]=p[i]; // appending the operator in `n3`
104 | n3[sz+1]='\0'; // every string ends with `\0`.
105 | strcat(n3,n2); //appending `n2` in `n3`.
106 | strcat(n3, ")"); // ending the experation with `)`
107 | PUSH(&s,n3); // push this expression`n3` as `variable_name` in stack.
108 | }
109 | i++;
110 | }while(p[i]!='\0'); // loop terminates when `\0` is scanned from `postfix`.
111 |
112 | char infix[100];
113 | POP(&s, infix);
114 | puts(infix);
115 | }
116 |
117 | int main()
118 | {
119 | char p[100]; //`p` to store postfix expression.
120 | printf("Enter the postfix : ");
121 | scanf("%s", p); // scan postfix expresstion from user.
122 | postfix_to_infix(p);
123 | }
124 |
--------------------------------------------------------------------------------
/prefix_to_infix/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | ->Author : Tirth Hihoriya
3 | ->Editor : Tirth Hihoriya
4 | ->E-mail : tirth.hihoriya@gmail.com
5 | ->Summary : Converting `prefix` to `infix` using STACK
6 | */
7 | #include
8 | #include // malloc, calloc
9 | #include // isalpha
10 | #include // strlen, strcpy, strcat
11 | #include // perror
12 |
13 | // Making a Structure of Stack that can store
14 | // a string
15 | struct stack
16 | {
17 | int top; // integer indicating the size of the string array
18 | // An array of maximum 100 string type element.
19 | char st[100][100];
20 | };
21 |
22 | // PUSH is a operation
23 | // to add an element onto the stack.
24 | void PUSH(struct stack *s,char n3[])
25 | {
26 | /*
27 | * Arguments: `s` (stack) -> A stack object in which you want to push.
28 | * `n3` (c_str) -> A string object to be pushed to the stack `s`.
29 | * Inserts the string `n3` on the top of the stack.
30 | * Returns: -
31 | */
32 |
33 | // If stack is full print error "Overflow!"
34 | if(s->top==100) perror("Overflow");
35 |
36 | // Else, increment the top attribute of the stack
37 | // and insert element at the new index of the `st` attribute
38 | // of stack.
39 | else
40 | {
41 | s->top++; // increment top
42 | strcpy(s->st[s->top],n3); // Copy the passed string onto the stack.
43 | }
44 |
45 | }
46 |
47 |
48 | // POP element from the top of the stack
49 | void POP(struct stack *s, char element[])
50 | {
51 | /*
52 | * Arguments: `s` (stack) -> A stack object from which the element
53 | * is being poped.
54 | * `element` (c_str) -> A string object in which the poped element
55 | * is stored.
56 | * Deletes top element from the `st` attribute of the stack object
57 | * and stores the deleted object in string `element`.
58 | * Returns: -
59 | */
60 |
61 | // If the stack is empty, print error "Underflow"
62 | if(s->top==-1) perror("Underflow\n");
63 |
64 | // Else, copy the top string and decrement `top` attribute by 1.
65 | else{
66 | strcpy(element,s->st[s->top]); // copy top of stack in `element`
67 | s->top--; // decrement top
68 | return;
69 | }
70 | }
71 |
72 |
73 | // Converts a prefix strint to infix.
74 | void prefix_to_infix(char p[])
75 | {
76 | // Make a stack object and initialize the `top` as -1.
77 | struct stack s = {-1};
78 | int i=strlen(p)-1; // used to iterate through the infix string.
79 | do
80 | {
81 | if(isalpha(p[i])) //isalpha(p[i]) will return true if
82 | //p[i] is alphabet i.e. for us `variable name`
83 | {
84 | char temp[100]; //it is temporary string to copy the `variable name`
85 | temp[0]=p[i];
86 | temp[1]='\0'; //because string should end with `\0`
87 | PUSH(&s,temp); //it will push the `temp` to the stack of string
88 | }
89 |
90 | // Now if while scanning the prefix if any operator aqppears then
91 | // POP the last `variable_name` then append the operator then
92 | // again POP the `variable_name` and also append it.
93 | else if(p[i]=='+' || p[i]=='-' || p[i]=='*' || p[i]=='/' || p[i]=='%') //these are some binary operator
94 | {
95 | char n3[100]; //`n3` is for the final string after appending the expresstion.
96 | strcpy(n3,"("); //initializing `n3` with `(` so that precedece is maintainted.
97 | char n2[100]; //`n2` is for the second `variable_name`
98 | POP(&s, n2);
99 | char n1[100]; //`n1` is for the first `variable_name`
100 | POP(&s, n1);
101 | strcat(n3,n2); // concatenating `n1` in `n3`.
102 | size_t sz = strlen(n3); // storing length of `n3` in `sz` variable.
103 | n3[sz]=p[i]; // appending the operator in `n3`
104 | n3[sz+1]='\0'; // every string ends with `\0`.
105 | strcat(n3,n1); //appending `n2` in `n3`.
106 | strcat(n3, ")"); // ending the expression with `)`
107 | PUSH(&s,n3); // push this expression`n3` as `variable_name` in stack.
108 | }
109 |
110 |
111 | i--;
112 | }while(i>=0); // loop terminates when `\0` is scanned from `prefix`.
113 |
114 | char infix[100];
115 | POP(&s, infix);
116 | printf("Infix expression is : ");
117 | puts(infix);
118 | }
119 |
120 | int main()
121 | {
122 | char p[100]; //`p` to store prefix expression.
123 | printf("Enter the prefix : ");
124 | scanf("%s", p); // scan prefix expression from user.
125 | prefix_to_infix(p);
126 | }
127 |
--------------------------------------------------------------------------------
/postfix_to_prefix/prefix_to_infix/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | ->Author : Tirth Hihoriya
3 | ->Editor : Tirth Hihoriya
4 | ->E-mail : tirth.hihoriya@gmail.com
5 | ->Summary : Converting `prefix` to `infix` using STACK
6 | */
7 | #include
8 | #include // malloc, calloc
9 | #include // isalpha
10 | #include // strlen, strcpy, strcat
11 | #include // perror
12 |
13 | // Making a Structure of Stack that can store
14 | // a string
15 | struct stack
16 | {
17 | int top; // integer indicating the size of the string array
18 | // An array of maximum 100 string type element.
19 | char st[100][100];
20 | };
21 |
22 | // PUSH is a operation
23 | // to add an element onto the stack.
24 | void PUSH(struct stack *s,char n3[])
25 | {
26 | /*
27 | * Arguments: `s` (stack) -> A stack object in which you want to push.
28 | * `n3` (c_str) -> A string object to be pushed to the stack `s`.
29 | * Inserts the string `n3` on the top of the stack.
30 | * Returns: -
31 | */
32 |
33 | // If stack is full print error "Overflow!"
34 | if(s->top==100) perror("Overflow");
35 |
36 | // Else, increment the top attribute of the stack
37 | // and insert element at the new index of the `st` attribute
38 | // of stack.
39 | else
40 | {
41 | s->top++; // increment top
42 | strcpy(s->st[s->top],n3); // Copy the passed string onto the stack.
43 | }
44 |
45 | }
46 |
47 |
48 | // POP element from the top of the stack
49 | void POP(struct stack *s, char element[])
50 | {
51 | /*
52 | * Arguments: `s` (stack) -> A stack object from which the element
53 | * is being poped.
54 | * `element` (c_str) -> A string object in which the poped element
55 | * is stored.
56 | * Deletes top element from the `st` attribute of the stack object
57 | * and stores the deleted object in string `element`.
58 | * Returns: -
59 | */
60 |
61 | // If the stack is empty, print error "Underflow"
62 | if(s->top==-1) perror("Underflow\n");
63 |
64 | // Else, copy the top string and decrement `top` attribute by 1.
65 | else{
66 | strcpy(element,s->st[s->top]); // copy top of stack in `element`
67 | s->top--; // decrement top
68 | return;
69 | }
70 | }
71 |
72 |
73 | // Converts a prefix strint to infix.
74 | void prefix_to_infix(char p[])
75 | {
76 | // Make a stack object and initialize the `top` as -1.
77 | struct stack s = {-1};
78 | int i=strlen(p)-1; // used to iterate through the infix string.
79 | do
80 | {
81 | if(isalpha(p[i])) //isalpha(p[i]) will return true if
82 | //p[i] is alphabet i.e. for us `variable name`
83 | {
84 | char temp[100]; //it is temporary string to copy the `variable name`
85 | temp[0]=p[i];
86 | temp[1]='\0'; //because string should end with `\0`
87 | PUSH(&s,temp); //it will push the `temp` to the stack of string
88 | }
89 |
90 | // Now if while scanning the prefix if any operator aqppears then
91 | // POP the last `variable_name` then append the operator then
92 | // again POP the `variable_name` and also append it.
93 | else if(p[i]=='+' || p[i]=='-' || p[i]=='*' || p[i]=='/' || p[i]=='%') //these are some binary operator
94 | {
95 | char n3[100]; //`n3` is for the final string after appending the expresstion.
96 | strcpy(n3,"("); //initializing `n3` with `(` so that precedece is maintainted.
97 | char n2[100]; //`n2` is for the second `variable_name`
98 | POP(&s, n2);
99 | char n1[100]; //`n1` is for the first `variable_name`
100 | POP(&s, n1);
101 | strcat(n3,n2); // concatenating `n1` in `n3`.
102 | size_t sz = strlen(n3); // storing length of `n3` in `sz` variable.
103 | n3[sz]=p[i]; // appending the operator in `n3`
104 | n3[sz+1]='\0'; // every string ends with `\0`.
105 | strcat(n3,n1); //appending `n2` in `n3`.
106 | strcat(n3, ")"); // ending the expression with `)`
107 | PUSH(&s,n3); // push this expression`n3` as `variable_name` in stack.
108 | }
109 |
110 |
111 | i--;
112 | }while(i>=0); // loop terminates when `\0` is scanned from `prefix`.
113 |
114 | char infix[100];
115 | POP(&s, infix);
116 | printf("Infix expression is : ");
117 | puts(infix);
118 | }
119 |
120 | int main()
121 | {
122 | char p[100]; //`p` to store prefix expression.
123 | printf("Enter the prefix : ");
124 | scanf("%s", p); // scan prefix expression from user.
125 | prefix_to_infix(p);
126 | }
127 |
--------------------------------------------------------------------------------
/trees/bst_iterative.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | typedef struct _node {
6 | int key;
7 | struct _node* right;
8 | struct _node* left;
9 | }Node;
10 |
11 | void createTree(Node **root, int key)
12 | {
13 | *root = (Node*)malloc(sizeof(Node));
14 | (*root)->key = key;
15 | (*root)->right = 0;
16 | (*root)->left = 0;
17 | }
18 |
19 | void insertRecursive(Node **root_ref, int key)
20 | {
21 | if(!*root_ref) {
22 | createTree(root_ref, key);
23 | return;
24 | }
25 | if(key < (*root_ref)->key) {
26 | if((*root_ref)->left==0) {
27 | Node *temp = (Node*)malloc(sizeof(Node));
28 | temp->key = key;
29 | temp->right = 0;
30 | temp->left = 0;
31 | (*root_ref)->left = temp;
32 | return;
33 | }
34 | insertRecursive(&(*root_ref)->left, key);
35 | }
36 | else if(key > (*root_ref)->key) {
37 | if((*root_ref)->right==0) {
38 | Node *temp = (Node*)malloc(sizeof(Node));
39 | temp->key = key;
40 | temp->right = 0;
41 | temp->left = 0;
42 | (*root_ref)->right = temp;
43 | return;
44 | }
45 | insertRecursive(&(*root_ref)->right, key);
46 | }
47 | else if(key == (*root_ref)->key) {
48 | printf(key + " already present in the tree!");
49 | return;
50 | }
51 | }
52 |
53 | void insertIterative(Node **root_ref, int key)
54 | {
55 | if(!*root_ref) {
56 | createTree(root_ref, key);
57 | return;
58 | }
59 | Node *root = *root_ref;
60 | Node *temp = root;
61 | while(1)
62 | {
63 | if(key < temp->key) {
64 | if(temp->left==0) {
65 | Node *new = (Node*)malloc(sizeof(Node));
66 | new->key = key;
67 | new->right = 0;
68 | new->left = 0;
69 | temp->left = new;
70 | return;
71 | }
72 | temp = temp->left;
73 | }
74 | else if(key > temp->key) {
75 | if(temp->right==0) {
76 | Node *new = (Node*)malloc(sizeof(Node));
77 | new->key = key;
78 | new->right = 0;
79 | new->left = 0;
80 | temp->right = new;
81 | return;
82 | }
83 | temp = temp->right;
84 | }
85 | else if(key == temp->key) {
86 | printf(key + " already present in the tree!");
87 | return;
88 | }
89 | }
90 | }
91 |
92 | void inorderTraversalRecursive(Node* root)
93 | {
94 | if(!root) return;
95 | inorderTraversalRecursive(root->left);
96 | printf("%d ", root->key);
97 | inorderTraversalRecursive(root->right);
98 | }
99 |
100 | void inorderTraversalIterative(Node* root)
101 | {
102 | Node* calls[100000];
103 | int top_call = -1;
104 | Node* temp;
105 | temp = root;
106 | while(temp!=0||top_call!=-1)
107 | {
108 | for(;temp;temp=temp->left) calls[++top_call]=temp;
109 | temp = calls[top_call--];
110 | printf("%d ", temp->key);
111 | temp = temp->right;
112 | }
113 | printf("\n");
114 | }
115 |
116 | void preorderTraversalIterative(Node* root)
117 | {
118 | Node* calls[100000];
119 | int top_call = -1;
120 | Node* temp = root;
121 | while(temp!=0 || top_call!=-1)
122 | {
123 | for(;temp;temp=temp->left){
124 | printf("%d ", temp->key);
125 | calls[++top_call] = temp;
126 | }
127 | temp = calls[top_call--];
128 | temp = temp->right;
129 | }
130 | printf("\n");
131 | }
132 |
133 | void postorderTraversalIterative(Node* root)
134 | {
135 | Node* calls[100000];
136 | int top_call = -1;
137 | Node* temp = root;
138 | do {
139 | while(root) {
140 | if(root->right) calls[++top_call] = root->right;
141 | calls[++top_call] = root;
142 | root = root->left;
143 | }
144 | root = calls[top_call--];
145 | if(root->right && calls[top_call]==root->right) {
146 | calls[top_call--];
147 | calls[++top_call] = root;
148 | root = root->right;
149 | }
150 | else {
151 | printf("%d ", root->key);
152 | root = 0;
153 | }
154 | }while(top_call!=-1);
155 | printf("\n");
156 | }
157 |
158 | int main(int argc, char** argv)
159 | {
160 | Node* root = 0;
161 | insertIterative(&root, 10);
162 | insertIterative(&root, 5);
163 | insertIterative(&root, 20);
164 | insertIterative(&root, 15);
165 | insertIterative(&root, 12);
166 | insertIterative(&root, 6);
167 | inorderTraversalIterative(root);
168 | preorderTraversalIterative(root);
169 | postorderTraversalIterative(root);
170 | }
--------------------------------------------------------------------------------
/prefix_to_postfix/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | ->Author : Tirth Hihoriya
3 | ->Editor : Tirth Hihoriya
4 | ->E-mail : tirth.hihoriya@gmail.com
5 | ->Summary : Converting `prefix` to `postfix` using STACK
6 | */
7 | #include
8 | #include // malloc, calloc
9 | #include // isalpha
10 | #include // strlen, strcpy, strcat
11 | #include // perror
12 |
13 | // Making a Structure of Stack that can store
14 | // a string
15 | struct stack
16 | {
17 | int top; // integer indicating the size of the string array
18 | // An array of maximum 100 string type element.
19 | char st[100][100];
20 | };
21 |
22 | // PUSH is a operation
23 | // to add an element onto the stack.
24 | void PUSH(struct stack *s,char n3[])
25 | {
26 | /*
27 | * Arguments: `s` (stack) -> A stack object in which you want to push.
28 | * `n3` (c_str) -> A string object to be pushed to the stack `s`.
29 | * Inserts the string `n3` on the top of the stack.
30 | * Returns: -
31 | */
32 |
33 | // If stack is full print error "Overflow!"
34 | if(s->top==100) perror("Overflow");
35 |
36 | // Else, increment the top attribute of the stack
37 | // and insert element at the new index of the `st` attribute
38 | // of stack.
39 | else
40 | {
41 | s->top++; // increment top
42 | strcpy(s->st[s->top],n3); // Copy the passed string onto the stack.
43 | }
44 |
45 | }
46 |
47 |
48 | // POP element from the top of the stack
49 | void POP(struct stack *s, char element[])
50 | {
51 | /*
52 | * Arguments: `s` (stack) -> A stack object from which the element
53 | * is being poped.
54 | * `element` (c_str) -> A string object in which the poped element
55 | * is stored.
56 | * Deletes top element from the `st` attribute of the stack object
57 | * and stores the deleted object in string `element`.
58 | * Returns: -
59 | */
60 |
61 | // If the stack is empty, print error "Underflow"
62 | if(s->top==-1) perror("Underflow\n");
63 |
64 | // Else, copy the top string and decrement `top` attribute by 1.
65 | else{
66 | strcpy(element,s->st[s->top]); // copy top of stack in `element`
67 | s->top--; // decrement top
68 | return;
69 | }
70 | }
71 |
72 |
73 | // Converts a prefix strint to postfix.
74 | void prefix_to_postfix(char p[])
75 | {
76 | // Make a stack object and initialize the `top` as -1.
77 | struct stack s = {-1};
78 | int i=strlen(p)-1; // used to iterate through the postfix string.
79 | do
80 | {
81 | if(isalpha(p[i])) //isalpha(p[i]) will return true if
82 | //p[i] is alphabet i.e. for us `variable name`
83 | {
84 | char temp[100]; //it is temporary string to copy the `variable name`
85 | temp[0]=p[i];
86 | temp[1]='\0'; //because string should end with `\0`
87 | PUSH(&s,temp); //it will push the `temp` to the stack of string
88 | }
89 |
90 | // Now if while scanning the prefix if any operator aqppears then
91 | // POP the last `variable_name` then append the operator then
92 | // again POP the `variable_name` and also append it.
93 | else if(p[i]=='+' || p[i]=='-' || p[i]=='*' || p[i]=='/' || p[i]=='%') //these are some binary operator
94 | {
95 | char n3[100]; //`n3` is for the final string after appending the expresstion.
96 | strcpy(n3,""); //initializing `n3` with `(` so that precedece is maintainted.
97 | char n2[100]; //`n2` is for the second `variable_name`
98 | POP(&s, n2);
99 | char n1[100]; //`n1` is for the first `variable_name`
100 | POP(&s, n1);
101 | strcat(n3,n2); // concatenating `n1` in `n3`.
102 | // every string ends with `\0`.
103 | strcat(n3,n1);
104 | size_t sz = strlen(n3); // storing length of `n3` in `sz` variable.
105 | n3[sz]=p[i]; // appending the operator in `n3`
106 | n3[sz+1]='\0'; //appending `n2` in `n3`.
107 | // ending the expression with `)`
108 | PUSH(&s,n3); // push this expression`n3` as `variable_name` in stack.
109 | }
110 |
111 |
112 | i--;
113 | }while(i>=0); // loop terminates when `\0` is scanned from `prefix`.
114 |
115 | char postfix[100];
116 | POP(&s, postfix);
117 | printf("Postfix expression is : ");
118 | puts(postfix);
119 | }
120 |
121 | int main()
122 | {
123 | char p[100]; //`p` to store prefix expression.
124 | printf("Enter the prefix : ");
125 | scanf("%s", p); // scan prefix expression from user.
126 | prefix_to_postfix(p);
127 | }
128 |
--------------------------------------------------------------------------------
/postfix_to_prefix/main.c:
--------------------------------------------------------------------------------
1 | /*
2 | ->Author : Tirth Hihoriya
3 | ->Editor : Tirth Hihoriya
4 | ->E-mail : tirth.hihoriya@gmail.com
5 | ->Summary : Converting `postfix` to `prefix` using STACK
6 | */
7 |
8 | #include
9 | #include
10 |
11 | #include
12 | #include // malloc, calloc
13 | #include // isalpha
14 | #include // strlen, strcpy, strcat
15 | #include // perror
16 |
17 | // Making a Structure of Stack that can store
18 | // a string
19 | struct stack
20 | {
21 | int top; // integer indicating the size of the string array
22 | // An array of maximum 100 string type element.
23 | char st[100][100];
24 | };
25 |
26 | // PUSH is a operation
27 | // to add an element onto the stack.
28 | void PUSH(struct stack *s,char n3[])
29 | {
30 | /*
31 | * Arguments: `s` (stack) -> A stack object in which you want to push.
32 | * `n3` (c_str) -> A string object to be pushed to the stack `s`.
33 | * Inserts the string `n3` on the top of the stack.
34 | * Returns: -
35 | */
36 |
37 | // If stack is full print error "Overflow!"
38 | if(s->top==100) perror("Overflow");
39 |
40 | // Else, increment the top attribute of the stack
41 | // and insert element at the new index of the `st` attribute
42 | // of stack.
43 | else
44 | {
45 | s->top++; // increment top
46 | strcpy(s->st[s->top],n3); // Copy the passed string onto the stack.
47 | }
48 |
49 | }
50 |
51 |
52 | // POP element from the top of the stack
53 | void POP(struct stack *s, char element[])
54 | {
55 | /*
56 | * Arguments: `s` (stack) -> A stack object from which the element
57 | * is being poped.
58 | * `element` (c_str) -> A string object in which the poped element
59 | * is stored.
60 | * Deletes top element from the `st` attribute of the stack object
61 | * and stores the deleted object in string `element`.
62 | * Returns: -
63 | */
64 |
65 | // If the stack is empty, print error "Underflow"
66 | if(s->top==-1) perror("Underflow\n");
67 |
68 | // Else, copy the top string and decrement `top` attribute by 1.
69 | else{
70 | strcpy(element,s->st[s->top]); // copy top of stack in `element`
71 | s->top--; // decrement top
72 | return;
73 | }
74 | }
75 |
76 |
77 | // Converts a postfix strint to infix.
78 | void postfix_to_infix(char p[])
79 | {
80 | // Make a stack object and initialize the `top` as -1.
81 | struct stack s = {-1};
82 | int i=0; // used to iterate through the infix string.
83 | do
84 | {
85 | if(isalpha(p[i])) //isalpha(p[i]) will return true if
86 | //p[i] is alphabet i.e. for us `variable name`
87 | {
88 | char temp[100]; //it is temporary string to copy the `variable name`
89 | temp[0]=p[i];
90 | temp[1]='\0'; //because string should end with `\0`
91 | PUSH(&s,temp); //it will push the `temp` to the stack of string
92 | }
93 |
94 | // Now if while scanning the postfix if any operator aqppears then
95 | // POP the last `variable_name` then append the operator then
96 | // again POP the `variable_name` and also append it.
97 | else if(p[i]=='+' || p[i]=='-' || p[i]=='*' || p[i]=='/' || p[i]=='%') //these are some binary operator
98 | {
99 | char n3[100]; //`n3` is for the final string after appending the expresstion.
100 | strcpy(n3,""); //initializing `n3` with `(` so that precedece is maintainted.
101 | char n2[100]; //`n2` is for the second `variable_name`
102 | POP(&s, n2);
103 | char n1[100]; //`n1` is for the first `variable_name`
104 | POP(&s, n1);
105 | size_t sz = strlen(n3);
106 | n3[sz]=p[i]; // appending the operator in `n3`
107 | n3[sz+1]='\0';
108 | strcat(n3,n1); // concatenating `n1` in `n3`.
109 | size_t sze = strlen(n3);
110 | n3[sze+1]='\0'; // storing length of `n3` in `sze` variable.
111 | // every string ends with `\0`.
112 | strcat(n3,n2); //appending `n2` in `n3`.
113 |
114 | PUSH(&s,n3); // push this expression`n3` as `variable_name` in stack.
115 | }
116 | i++;
117 | }while(p[i]!='\0'); // loop terminates when `\0` is scanned from `postfix`.
118 |
119 | char infix[100];
120 | POP(&s, infix);
121 | puts(infix);
122 | }
123 |
124 | int main()
125 | {
126 | char p[100]; //`p` to store postfix expression.
127 | printf("Enter the postfix : ");
128 | scanf("%s", p); // scan postfix expresstion from user.
129 | postfix_to_infix(p);
130 | }
131 |
--------------------------------------------------------------------------------
/trees/bst.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | typedef struct node Node;
5 | typedef struct node* tree_iterator;
6 |
7 | struct node
8 | {
9 | int key;
10 | tree_iterator parent, left, right;
11 | };
12 |
13 | int totalNodesInTree(tree_iterator root)
14 | {
15 | if(root == NULL) return 0;
16 | return totalNodesInTree(root->left) + totalNodesInTree(root->right) + 1;
17 | }
18 |
19 | tree_iterator create(int key)
20 | {
21 | tree_iterator root = (tree_iterator)malloc(sizeof(Node));
22 | root->key = key;
23 | root->left = 0;
24 | root->right = 0;
25 | root->parent = 0;
26 | return root;
27 | }
28 |
29 | tree_iterator insert(int key, tree_iterator root)
30 | {
31 | tree_iterator it = root;
32 | if(root==0) return root;
33 | while(1)
34 | {
35 | if(key == it->key)
36 | {
37 | printf("Node with same value exists!\n\nTerminating Program...\n\n");
38 | exit(1);
39 | }
40 | else if(key < it->key){
41 | if(it->left == 0) break;
42 | it = it->left;
43 | }
44 | else{
45 | if(it->right == 0) break;
46 | it = it->right;
47 | }
48 | }
49 | tree_iterator newNode = (tree_iterator)malloc(sizeof(Node));
50 | newNode->key = key;
51 | newNode->parent = it;
52 | newNode->left = 0;
53 | newNode->right = 0;
54 | if(keykey) it->left = newNode;
55 | else it->right = newNode;
56 | return root;
57 | }
58 |
59 | tree_iterator minValueRoot(tree_iterator root)
60 | {
61 | if(0 == root) return root;
62 | if(0 == root->left) return root;
63 | return minValueRoot(root->left);
64 | }
65 |
66 | tree_iterator delete(int key, tree_iterator root)
67 | {
68 | if(0 == root) return root;
69 | if(key < root->key) //the key is in the left branch
70 | {
71 | if(0 == root->left)
72 | {
73 | printf("Node with %d value dont exists!\n\nTerminating Program...\n\n", key);
74 | exit(1);
75 | }
76 | root->left = delete(key, root->left);
77 | return root;
78 | }
79 | else if(key > root->key) //the key is in the right branch
80 | {
81 | if(0 == root->right)
82 | {
83 | printf("Node with %d value dont exists!\n\nTerminating Program...\n\n", key);
84 | exit(1);
85 | }
86 | root->right = delete(key, root->right);
87 | return root;
88 | }
89 | else //the root has key
90 | {
91 | if(0 == root->left && 0 == root->right) //has no child
92 | {
93 | free(root);
94 | return 0;
95 | }
96 | else if(0 == root->right) //has one child(left)
97 | {
98 | tree_iterator temp_node = root->left;
99 | temp_node->parent = root->parent;
100 | free(root);
101 | return temp_node;
102 | }
103 | else if(0 == root->left) //has one child(right)
104 | {
105 | tree_iterator temp_node = root->right;
106 | temp_node->parent = root->parent;
107 | free(root);
108 | return temp_node;
109 | }
110 | else //has two child
111 | {
112 | tree_iterator mvr = minValueRoot(root->right);
113 | root->key = mvr->key;
114 | root->right = delete(mvr->key, root->right);
115 | }
116 | }
117 | return root;
118 | }
119 |
120 | void inorder(tree_iterator root)
121 | {
122 | if(root==0) return;
123 | inorder(root->left);
124 | printf("%d ", root->key);
125 | inorder(root->right);
126 | }
127 |
128 | void postorder(tree_iterator root)
129 | {
130 | if(root==0) return;
131 | postorder(root->left);
132 | postorder(root->right);
133 | printf("%d ", root->key);
134 | }
135 |
136 | void preorder(tree_iterator root)
137 | {
138 | if(root==0) return;
139 | printf("%d ", root->key);
140 | preorder(root->left);
141 | preorder(root->right);
142 | }
143 |
144 | void printTree(tree_iterator root, int space)
145 | {
146 | if(0 == root) return;
147 | printTree(root->right, space+4); //for indent we add space by 4
148 | printf("\n");
149 | for(int s=0; skey);
154 | printTree(root->left, space+4);
155 | }
156 |
157 | int main()
158 | {
159 | tree_iterator root = create(10);
160 | root = insert(20,root);
161 | root = insert(5,root);
162 | root = insert(1,root);
163 | root = insert(8,root);
164 | root = insert(6,root);
165 | root = delete(5,root);
166 |
167 | printf("Tree shape:\n");
168 | printTree(root, 0);
169 | printf("\nPreorder: ");
170 | preorder(root);
171 | printf("\nInorder: ");
172 | inorder(root);
173 | printf("\nPostorder: ");
174 | postorder(root);
175 | int nb_nodes = totalNodesInTree(root);
176 | printf("\nTotal nodes: %d\n", nb_nodes);
177 | }
178 |
--------------------------------------------------------------------------------
/linked_list_algorithms/polynomial_addition.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | typedef struct node* iterator;
5 |
6 | typedef struct node
7 | {
8 | int coef;
9 | int expo;
10 | struct node* next;
11 | }Node;
12 |
13 | iterator create_singly_linked_list(int coef, int expo)
14 | {
15 | iterator head = (iterator)malloc(sizeof(Node));
16 | head->coef = coef;
17 | head->expo = expo;
18 | head->next = 0;
19 | return head;
20 | }
21 |
22 | iterator insert_inorder(int coef, int expo, iterator head)
23 | {
24 | iterator it = head;
25 | iterator prev = 0;
26 | if(head->expo < expo)
27 | {
28 | iterator new = (iterator)malloc(sizeof(Node));
29 | new->coef = coef;
30 | new->expo = expo;
31 | new->next = head;
32 | head = new;
33 | return head;
34 | }
35 | while(it->expo > expo)
36 | {
37 | if(it->next == 0)
38 | {
39 | if(it->coef == coef)
40 | {
41 | it->coef += coef;
42 | return head;
43 | }
44 | iterator new = (iterator)malloc(sizeof(Node));
45 | new->coef = coef;
46 | new->expo = expo;
47 | new->next = 0;
48 | it->next = new;
49 | return head;
50 | }
51 | prev = it;
52 | it = it->next;
53 | }
54 | if(it->expo == expo)
55 | {
56 | it->coef += coef;
57 | return head;
58 | }
59 | iterator new = (iterator)malloc(sizeof(Node));
60 | new->coef = coef;
61 | new->expo = expo;
62 | new->next = it;
63 | prev->next = new;
64 | return head;
65 | }
66 |
67 | iterator insert_at_end(int coef, int expo, iterator head)
68 | {
69 | iterator it = head;
70 | while(it->next != 0) it = it->next;
71 | iterator new = (iterator)malloc(sizeof(Node));
72 | new->coef = coef;
73 | new->expo = expo;
74 | new->next = 0;
75 | it->next = new;
76 | return head;
77 | }
78 |
79 | iterator add_polynomials(iterator head1, iterator head2)
80 | {
81 | iterator temp1 = head1;
82 | iterator temp2 = head2;
83 | iterator head3 = 0;
84 | while(temp1 != 0 && temp2 != 0)
85 | {
86 | if(temp1->expo < temp2->expo)
87 | {
88 | if(head3 == 0){
89 | head3 = create_singly_linked_list(temp2->coef, temp2->expo);
90 | }
91 | else{
92 | head3 = insert_at_end(temp2->coef, temp2->expo, head3);
93 | }
94 | temp2 = temp2->next;
95 | }
96 | else if(temp1->expo > temp2->expo)
97 | {
98 | if(head3 == 0){
99 | head3 = create_singly_linked_list(temp1->coef, temp1->expo);
100 | }
101 | else{
102 | head3 = insert_at_end(temp1->coef, temp1->expo, head3);
103 | }
104 | temp1 = temp1->next;
105 | }
106 | else
107 | {
108 | if(head3 == 0){
109 | head3 = create_singly_linked_list(temp1->coef + temp2->coef, temp1->expo);
110 | }
111 | else{
112 | head3 = insert_at_end(temp1->coef + temp2->coef, temp1->expo, head3);
113 | }
114 | temp1 = temp1->next;
115 | temp2 = temp2->next;
116 | }
117 | }
118 | iterator it = head3;
119 | while(it->next != 0) it = it->next;
120 | if(temp1 == 0 && temp2 != 0) it->next = temp2;
121 | else if(temp2 == 0 && temp1 != 0) it->next = temp1;
122 | return head3;
123 | }
124 |
125 | void display_sll(iterator head)
126 | {
127 | iterator it = head;
128 | while(it->next != 0)
129 | {
130 | printf("%d * x^%d + ", it->coef, it->expo);
131 | it = it->next;
132 | }
133 | printf("%d * x^%d", it->coef, it->expo);
134 | printf("\n");
135 | }
136 |
137 | int main()
138 | {
139 | iterator head1 = 0;
140 | iterator head2 = 0;
141 | int terms1, terms2;
142 | printf("Enter the number of terms in first polynomial: ");
143 | scanf("%d", &terms1);
144 | printf("Enter the coeficient and exponent for all terms of first polynomial: ");
145 | for(int i=0;iThis project is meant to help beginners understand and code Data Structures and Algorithms
3 | in C. This project strictly follows the book `Introduction to Algorithms` by Thomas H. Cormen.
4 | Any beginners strugling with Data Structures and Algorithms are highly recommended to follow
5 | the book. Most of the code is documented properly for beginner audiences to understand easily.
6 | Minimum utilities and libraries are used in case the targeted audience ins't familiar with them.
7 |
This project is still in development stage and needs more contributors.
8 |
Read contributing guidelines in case you want to contribute to this project.
9 |
10 | ## Algorithms Implemented
11 |
Algorithms have been mostly implemented in C++ and partially documented. The algorithms implemented are:
12 |
13 |
Insertion Sort. (location: Algorithms.cpp, line on:[150-165])
14 |
Heap Sort (location: Algorithms.cpp, line no:[331-342])
15 |
Quick Sort (location: Algorithms.cpp, line no:[368-378])
16 |
Randomized Quick Sort (location: Algorithms.cpp, line no:[360-366])
17 |
Counting Sort (location: Algorithms.cpp, line no:[392-408])
18 |
Merge Sort (location: Algorithms.cpp, line no:[410-467])
19 |
Selection Sort (location: Algorithms.cpp, line no:[484-500])
20 |
Bubble Sort (location: Algorithms.cpp, line no:[474-482])
21 |
Linear Search (location: Algorithms.cpp, line no:[133-143])
22 |
Binary Search (location: Algorithms.cpp, line no:[111-124])
23 |
Maximum Subarry Problem solved using brute forse, devide and concour and linear methods. (location: Algorithms.cpp, line no:[582-691])
24 |
Infix to Reverse Polish (postfix) using STACK in C (location: infix_to_postfix/main.c)
25 |
Infix to Polish (prefix) using STACK in C (location: infix_to_prefix/main.c)
26 |
Reverse Polish (postfix) to Polish (prefix) using STACK in C (location: postfix_to_prefix/main.c)
27 |
Reverse Polish (postfix) to Infix using STACK in C (location: postfix_to_infix/main.c)
28 |
Polish (prefix) to Reverse Polish (postfix) using STACK in C (location: prefix_to_postfix/main.c)
29 |
Polish (prefix) to Infix using STACK in C (location: profix_to_infix/main.c)
30 |
31 |
32 |
All the algorithms will be fully documented and implemented in C soon!
33 |
34 | ## Data Structures Implemented
35 |
All the Data Structures have been implemented in C. The implemented Data Structures are:
36 |
37 |
Stack (fully documented) (C implementation: stack_as_static_array.c, C++ implementtation: stack/stack/headers/Stack.h)
38 |
Queue (documented) (C implementation: queue_using_static_array.c, C++ implementtation: queue/queue/headers/Queue.h)
39 |
Heap (documented) (location: Algorithms.cpp, line no:[168-342])
40 |
Priority Queue (documented) (C implementation: priority_queue.c, C++ implementation: Algorithms.cpp, line no:[168-342])
Currently under devlopment, some of the Dynamic and Greedy Algoruthms have been implemented in this section. The implementations include:
52 |
53 |
Fibonacci Series
54 |
Rod Cutting Problem
55 |
Matrix Chain Multiplication Problem
56 |
Longest Common Subsequence Problem
57 |
58 |
59 |
When does Dynamic Algorithm apply?
60 |
61 |
62 |
optimal substructure.
63 |
Property of independence holds.
64 |
Property of linearity holds.
65 |
Choices hold both for subproblems and problems.
66 |
67 |
overlapping subproblems.
68 |
69 |
70 |
71 |
Elements of Dynamic Programming:
72 |
73 |
74 |
Optimal Substucture.
75 |
Overlapping Subproblems.
76 |
Reconstructing a optimal solution.
77 |
Memoization for top-down approach.
78 |
79 |
80 |
81 |
82 |
Attack plan:
83 |
84 |
85 |
Characterize the stucture of an optimum solution.
86 |
Recursively define the value of an optimum solution.
87 |
Compute the value of optimum solution.
88 |
Construct an optimal solution from computed information.
89 |
90 |
91 |
92 |
Examples:
93 |
94 |
95 |
Rod cutting Problem.
96 |
Matrix Chain Multiplication.
97 |
Shortest Path in unweighed directed graph.
98 |
Longest Common Sub-Sequence.
99 |
100 |
101 |
102 |
103 |
Where it doesn't apply:
104 |
105 |
106 |
Longest Path in unweighed directed graph.
107 |
Rod cutting with limit of cuts.
108 |
109 |
110 |
111 |
112 |
113 | ## Thanking you!
114 | Please read the contributing guidelines if you wish to contribute!
115 |
--------------------------------------------------------------------------------
/paranthesized_infix_to_polish_and_reverse_polish_converter.c:
--------------------------------------------------------------------------------
1 | /*
2 | * @autor: tirthasheshpatel
3 | * e-mail: tirthasheshpatel@gmail.com
4 | * Summary: Implemented stack. Using stack,
5 | * implemented the infix expression to
6 | * reverse polish expression converter.
7 | * This version supports paranthesis and
8 | * other basic operators -> + - * / ^
9 | */
10 |
11 | #include // Handles standard input/output
12 | #include // Error Handling library
13 | #include
14 | #include
15 | #include
16 |
17 | // The maximum number of elements that can be stored in a stack.
18 | #define MAX 65535
19 |
20 | // Structure of stack
21 | struct stack
22 | {
23 | // A integer pointing at the top of the stack.
24 | int top;
25 | // A array to hold the values of stack.
26 | char arr[MAX+1];
27 | }s;
28 |
29 | // Deletes and returns the top element in a stack.
30 | char POP(struct stack* s)
31 | {
32 | // IMPLEMENT POP
33 |
34 | // Handle error when stack is empty.
35 | if(s->top == -1) perror("Stack Underflow!");
36 |
37 | // Get a copy of value at the top of the stack
38 | // in a variable `element` that we are going to return.
39 | char element = s->arr[s->top];
40 |
41 | // Initialize the value at the top of the stack again to 0.
42 | s->arr[s->top] = 0;
43 | // Decrease the value of `top` by 1.
44 | s->top--;
45 |
46 | // Finally, return `element`.
47 | return element;
48 | }
49 |
50 | // Adds a element onto the top of stack
51 | void PUSH(struct stack* s, char value)
52 | {
53 | // IMPLEMENT PUSH
54 |
55 | // Handle error in case the stack has reached its maximum limit `MAX`.
56 | if(s->top == MAX) perror("Stack Overflow!");
57 |
58 | // Increase the value of `top` by 1.
59 | s->top++;
60 | // Insert element at the index `top`.
61 | s->arr[s->top] = value;
62 | }
63 |
64 | // f returns the precedence of the symbol in the *input* string.
65 | int f(char a)
66 | {
67 | // if a is a alphabet (variable) return input precedence 7.
68 | if(isalpha(a)) return 7;
69 |
70 | // Else if a is a `*` or `/` return lower precedence than variable
71 | if(a == '*' || a == '/') return 3;
72 |
73 | // Else if a is a `+` or `-` return lower precedence than `*` or `/`
74 | if(a == '+' || a == '-') return 1;
75 |
76 | if(a == '^') return 6;
77 |
78 | if(a == '(') return 9;
79 |
80 | // Else return lowest precednece!
81 | if(a == '#' || a == ')') return 0;
82 | else return -200;
83 | }
84 |
85 | // g returns the precedence of the symbol in the stack.
86 | int g(char a)
87 | {
88 | // if a is a alphabet (variable) return precedence 8 on stack
89 | if(isalpha(a)) return 8;
90 |
91 | // Else if a is a `*` or `/` return lower precedence than variable
92 | if(a == '*' || a == '/') return 4;
93 |
94 | // Else if a is a `+` or `-` return lower precedence than `*` or `/`
95 | if(a == '+' || a == '-') return 2;
96 |
97 | if(a == '^') return 5;
98 |
99 | if(a == '(') return 0;
100 |
101 | // Else return lowest precednece!
102 | if(a == '#' || a == ')') return -1;
103 |
104 | else return -1;
105 | }
106 |
107 | // Returns the rank of the character literal
108 | int r(char a)
109 | {
110 | // If the character is `#` return rank 0.
111 | // Else if it is a alphabet (variable) return 1.
112 | // Else return -1;
113 | if(a == '#') return 0;
114 | if(isalpha(a)) return 1;
115 | return -1;
116 | }
117 |
118 | // Use this function to parse infix to reverse polish
119 | void parse_infix_to_r_polish(char infix[], char r_polish[])
120 | {
121 | // Declare a string to store the reverse polish string and initialize rank to 0
122 | int rank=0;
123 |
124 | // Creaste stack s
125 | struct stack s = {-1,0};
126 | // i and j will be used to access elements of infix and r_polish resp.
127 | int i=0,j=0;
128 | PUSH(&s, '#'); // Initialize stack by pushing `#` as the first character.
129 |
130 | // Until we dont reach the end of the infix string, parse it.
131 | while(infix[i] != '#')
132 | {
133 | // if precedence of element at the top of the stack is
134 | // more than that of next element of infix string,
135 | // shift the element from the stack to the reverse polish string.
136 | while( g(s.arr[s.top]) >= f(infix[i]) )
137 | {
138 | char temp = POP(&s); // first pop
139 | if(temp != '(' && temp != ')'){
140 | r_polish[j++] = temp; // put that char to next empty index in the `r_polish` string.
141 | rank += r(temp); // update rank
142 | }
143 | }
144 |
145 | // Once the shifting is done, push new element to the stack
146 | PUSH(&s, infix[i++]);
147 | }
148 |
149 | // Shift all the remaining elements from the stack to `r_polish` string.
150 | while(s.arr[s.top]!='#'){
151 | char temp = POP(&s); // pop
152 | if(temp != '(' && temp != ')'){
153 | r_polish[j++] = temp; // put that char to next empty index in the `r_polish` string.
154 | rank += r(temp); // update rank
155 | }
156 | }
157 |
158 | // End the `r_polish` string.
159 | r_polish[j] = '\0';
160 |
161 | // Check if rank is equal to 1. If not, show error in input.
162 | if(rank != 1){
163 | printf("Error in rank! Check your input!\n");
164 | return;
165 | }
166 |
167 | }
168 |
169 | void cust_strrev(char str1[], char str2[])
170 | {
171 | size_t sz = strlen(str1);
172 | int i=0, j = sz-1;
173 | while(j >= 0)
174 | {
175 | str2[i++] = str1[j--];
176 | }
177 | str2[i] = '\0';
178 | while(i-- >= 0)
179 | {
180 | if(str2[i] == '(') str2[i] = ')';
181 | else if(str2[i] == ')') str2[i] = '(';
182 | else continue;
183 | }
184 | }
185 |
186 | void parse_infix_to_polish(char infix[], char polish[])
187 | {
188 | char rev_infix[1000];
189 | char rev_polish[1000];
190 | cust_strrev(infix, rev_infix);
191 | strcat(rev_infix, "#");
192 | parse_infix_to_r_polish(rev_infix, rev_polish);
193 | cust_strrev(rev_polish, polish);
194 | }
195 |
196 | int main()
197 | {
198 | printf("Enter a infix string using any variables like a, b, c, etc.\nDon't use any whitespaces\nEnter string: ");
199 | char infix_string[1000];
200 | scanf("%s", infix_string);
201 | char polish[1000];
202 | parse_infix_to_polish(infix_string, polish);
203 | puts(polish);
204 |
205 | // parse_infix(infix_string);
206 | }
--------------------------------------------------------------------------------
/Graph Algorithms/boilerplate.h:
--------------------------------------------------------------------------------
1 | /*
2 | * author: @tirthasheshpatel
3 | * Base code for all Graph Algorithms
4 | * Contains implementation of: Queue, Stack, Linked Lists.
5 | */
6 |
7 | #ifndef GUARD_BOILERPLATE_H
8 | #define GUARD_BOILERPLATE_H
9 |
10 | // Importing dependencies
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 | #define INF 2147483647;
18 |
19 | // Making the `size_t` keyword easier to interpret.
20 | typedef size_t size_type;
21 | // A pointer to the nodes in the list
22 | // is defined for easy use in functions.
23 | typedef struct Node* list_iterator;
24 | typedef struct vertex* vertex_iterator;
25 |
26 |
27 | // A structure of `Node` used in the
28 | // doubly linked list for storing keys
29 | // and pointers to neighbouring Nodes.
30 | struct Node
31 | {
32 | vertex_iterator key; // Stores the value to be accessed by the user at runtime.
33 | // Pointers to the next and previous elements in the list.
34 | list_iterator prev, next;
35 | };
36 |
37 |
38 | typedef struct vertex
39 | {
40 | int value;
41 | char color;
42 | int depth;
43 | int start;
44 | int end;
45 | vertex_iterator parent;
46 | list_iterator adj_list;
47 | }Vertex;
48 |
49 |
50 | typedef struct queue
51 | {
52 | int size;
53 | int front;
54 | int rear;
55 | vertex_iterator* que;
56 | }Queue;
57 |
58 | typedef struct stack
59 | {
60 | int empty;
61 | list_iterator head;
62 | list_iterator tail;
63 | }Stack;
64 |
65 | void init_stack(Stack* s)
66 | {
67 | s->empty = 1;
68 | s->head = s->tail = 0;
69 | }
70 |
71 | void push(Stack* s, vertex_iterator key)
72 | {
73 | if(s->empty == 1)
74 | {
75 | s->empty = 0;
76 | s->head = (list_iterator)malloc(sizeof(struct Node));
77 | s->head->key = key;
78 | s->head->next = 0;
79 | s->head->prev = 0;
80 | s->tail = s->head;
81 | }
82 | else
83 | {
84 | s->tail->next = (list_iterator)malloc(sizeof(struct Node));
85 | s->tail->next->key = key;
86 | s->tail->next->next = 0;
87 | s->tail->next->prev = s->tail;
88 | s->tail = s->tail->next;
89 | }
90 | }
91 |
92 | vertex_iterator pop(Stack* s)
93 | {
94 | if(s->empty == 1)
95 | {
96 | printf("Stack empty!");
97 | exit(1);
98 | }
99 | else if(s->head == s->tail)
100 | {
101 | vertex_iterator element = s->head->key;
102 | s->empty = 1;
103 | s->head = s->tail = 0;
104 | return element;
105 | }
106 | vertex_iterator element = s->tail->key;
107 | s->tail = s->tail->prev;
108 | s->tail->next = 0;
109 | return element;
110 | }
111 |
112 |
113 | // A function that creates and initializes the
114 | // doubly linked list.
115 | list_iterator create_doubly_linked_list(vertex_iterator key)
116 | {
117 |
118 | /*
119 | * Arguments: `key` (int) -> A value to be stored in the list.
120 | * Creates a doubly linked list.
121 | * Returns : `first` (list_iterator) -> A pointer to the first element of list.
122 | */
123 |
124 | // Step 1: Allocate memory to store a variable of type `Node`.
125 | list_iterator first = (list_iterator)malloc(sizeof(struct Node));
126 | // Step 2: Initialize key as provided by the user.
127 | first->key = key;
128 | // Step 3: First element in the list so it doesn't
129 | // have next and prev elements.
130 | first->prev = 0;
131 | first->next = 0;
132 |
133 | // Step 4: Return the pointer to allocated node.
134 | return first;
135 | }
136 |
137 | // Insert a node at the front of the linked list in O(1) time.
138 | list_iterator insert_in_front_of_the_doubly_linked_list(list_iterator first, vertex_iterator key)
139 | {
140 | /*
141 | * Argments: `first` (list_iterator) -> A pointer to the first element in the list.
142 | * Initialize the list using `create_doubly_linked_list()`
143 | * to get this pointer variable
144 | * `key` (int) -> The element to be stored in the list.
145 | * This function is used to insert a Node at the front of the
146 | * doubly linked list. The Node is intialized by the provided value
147 | * of the key and other attributes are initalized according to
148 | * the previously allocated nodes.
149 | * Returns: `new_node` (list_iterator) -> A pointer variable pointing at the new
150 | * Node inserted using this function.
151 | */
152 |
153 | // Step 1: Allocate memory for the new node to be stored.
154 | list_iterator new_node = (list_iterator)malloc(sizeof(struct Node));
155 |
156 | // Step 2: Initialize the key using the key provided by user.
157 | // Step 3: This node has the `next` member as `first`
158 | // which used to be the first Node in the list.
159 | // Step 4: Also, don't forget to add the newly allocated
160 | // node as the previous member of the `first` Node.
161 | // Step 5: The previous member is still `NULL`.
162 | new_node->key = key;
163 | new_node->next = first;
164 | first->prev = new_node;
165 | new_node->prev = 0;
166 |
167 | // Step 6: Return the newly allocated node which will act as the 'first' node in the list.
168 | return new_node;
169 | }
170 |
171 | void initalize_queue(Queue* q, int size)
172 | {
173 | q->size = size;
174 | q->front = q->rear = -1;
175 | q->que = (vertex_iterator*)malloc(size*sizeof(vertex_iterator));
176 | for(int i=0;isize;i++)
177 | {
178 | q->que[i] = 0;
179 | }
180 | // printf("Queue Initialized!!\n\n");
181 | }
182 |
183 | void reintialize_in_queue(Queue* q)
184 | {
185 | q->que[q->front] = 0;
186 | }
187 |
188 | void enqueue(Queue* q, vertex_iterator val)
189 | {
190 | if(q->front==(q->rear+1)%q->size){
191 | printf("\nQueue Overflow!");
192 | exit(1);
193 | }
194 | else
195 | {
196 | q->rear=(q->rear+1)%q->size;
197 | q->que[q->rear]=val;
198 | if(q->front==-1)
199 | q->front=0;
200 | }
201 | }
202 |
203 |
204 | vertex_iterator dequeue(Queue* q)
205 | {
206 | if(q->front==-1)
207 | {
208 | printf("\nQueue Underflow!");
209 | exit(1);
210 | }
211 | else
212 | {
213 | vertex_iterator ele;
214 | ele=q->que[q->front];
215 | if(q->front==q->rear)
216 | {
217 | reintialize_in_queue(q);
218 | q->front=-1;
219 | q->rear=-1;
220 | }
221 | else
222 | {
223 | reintialize_in_queue(q);
224 | q->front=(q->front+1)%q->size;
225 | }
226 | return ele;
227 | }
228 | }
229 |
230 | #endif
--------------------------------------------------------------------------------
/linked_list_algorithms/circular_linked_list.c:
--------------------------------------------------------------------------------
1 | /*
2 | * C Program to Demonstrate Circular Single Linked List
3 | */
4 | #include
5 | #include
6 |
7 | struct node
8 | {
9 | int data;
10 | struct node *link;
11 | };
12 |
13 | struct node *head = NULL, *x, *y, *z;
14 |
15 | void create();
16 | void ins_at_beg();
17 | void ins_at_pos();
18 | void del_at_beg();
19 | void del_at_pos();
20 | void traverse();
21 | void search();
22 | void sort();
23 | void update();
24 | void rev_traverse(struct node *p);
25 |
26 | void main()
27 | {
28 | int ch;
29 |
30 | printf("\n 1.Creation \n 2.Insertion at beginning \n 3.Insertion at remaining");
31 | printf("\n4.Deletion at beginning \n5.Deletion at remaining \n6.traverse");
32 | printf("\n7.Search\n8.sort\n9.update\n10.Exit\n");
33 | while (1)
34 | {
35 | printf("\n Enter your choice:");
36 | scanf("%d", &ch);
37 | switch(ch)
38 | {
39 | case 1:
40 | create();
41 | break;
42 | case 2:
43 | ins_at_beg();
44 | break;
45 | case 3:
46 | ins_at_pos();
47 | break;
48 | case 4:
49 | del_at_beg();
50 | break;
51 | case 5:
52 | del_at_pos();
53 | break;
54 | case 6:
55 | traverse();
56 | break;
57 | case 7:
58 | search();
59 | break;
60 | case 8:
61 | sort();
62 | break;
63 | case 9:
64 | update();
65 | break;
66 | case 10:
67 | rev_traverse(head);
68 | break;
69 | default:
70 | exit(0);
71 | }
72 | }
73 | }
74 |
75 | /*Function to create a new circular linked list*/
76 | void create()
77 | {
78 | int c;
79 |
80 | x = (struct node*)malloc(sizeof(struct node));
81 | printf("\n Enter the data:");
82 | scanf("%d", &x->data);
83 | x->link = x;
84 | head = x;
85 | printf("\n If you wish to continue press 1 otherwise 0:");
86 | scanf("%d", &c);
87 | while (c != 0)
88 | {
89 | y = (struct node*)malloc(sizeof(struct node));
90 | printf("\n Enter the data:");
91 | scanf("%d", &y->data);
92 | x->link = y;
93 | y->link = head;
94 | x = y;
95 | printf("\n If you wish to continue press 1 otherwise 0:");
96 | scanf("%d", &c);
97 | }
98 | }
99 |
100 | /*Function to insert an element at the begining of the list*/
101 |
102 | void ins_at_beg()
103 | {
104 | x = head;
105 | y = (struct node*)malloc(sizeof(struct node));
106 | printf("\n Enter the data:");
107 | scanf("%d", &y->data);
108 | while (x->link != head)
109 | {
110 | x = x->link;
111 | }
112 | x->link = y;
113 | y->link = head;
114 | head = y;
115 | }
116 |
117 | /*Function to insert an element at any position the list*/
118 |
119 | void ins_at_pos()
120 | {
121 | struct node *ptr;
122 | int c = 1, pos, count = 1;
123 |
124 | y = (struct node*)malloc(sizeof(struct node));
125 | if (head == NULL)
126 | {
127 | printf("cannot enter an element at this place");
128 | }
129 | printf("\n Enter the data:");
130 | scanf("%d", &y->data);
131 | printf("\n Enter the position to be inserted:");
132 | scanf("%d", &pos);
133 | x = head;
134 | ptr = head;
135 | while (ptr->link != head)
136 | {
137 | count++;
138 | ptr = ptr->link;
139 | }
140 | count++;
141 | if (pos > count)
142 | {
143 | printf("OUT OF BOUND");
144 | return;
145 | }
146 | while (c < pos)
147 | {
148 | z = x;
149 | x = x->link;
150 | c++;
151 | }
152 | y->link = x;
153 | z->link = y;
154 | }
155 |
156 | /*Function to delete an element at any begining of the list*/
157 |
158 | void del_at_beg()
159 | {
160 | if (head == NULL)
161 | printf("\n List is empty");
162 | else
163 | {
164 | x = head;
165 | y = head;
166 | while (x->link != head)
167 | {
168 | x = x->link;
169 | }
170 | head = y->link;
171 | x->link = head;
172 | free(y);
173 | }
174 | }
175 |
176 | /*Function to delete an element at any position the list*/
177 |
178 | void del_at_pos()
179 | {
180 | if (head == NULL)
181 | printf("\n List is empty");
182 | else
183 | {
184 | int c = 1, pos;
185 | printf("\n Enter the position to be deleted:");
186 | scanf("%d", &pos);
187 | x = head;
188 | while (c < pos)
189 | {
190 | y = x;
191 | x = x->link;
192 | c++;
193 | }
194 | y->link = x->link;
195 | free(x);
196 | }
197 | }
198 |
199 | /*Function to display the elements in the list*/
200 |
201 | void traverse()
202 | {
203 | if (head == NULL)
204 | printf("\n List is empty");
205 | else
206 | {
207 | x = head;
208 | while (x->link != head)
209 | {
210 | printf("%d->", x->data);
211 | x = x->link;
212 | }
213 | printf("%d", x->data);
214 | }
215 | }
216 |
217 | /*Function to search an element in the list*/
218 |
219 | void search()
220 | {
221 | int search_val, count = 0, flag = 0;
222 | printf("\nenter the element to search\n");
223 | scanf("%d", &search_val);
224 | if (head == NULL)
225 | printf("\nList is empty nothing to search");
226 | else
227 | {
228 | x = head;
229 | while (x->link != head)
230 | {
231 | if (x->data == search_val)
232 | {
233 | printf("\nthe element is found at %d", count);
234 | flag = 1;
235 | break;
236 | }
237 | count++;
238 | x = x->link;
239 | }
240 | if (x->data == search_val)
241 | {
242 | printf("element found at postion %d", count);
243 | }
244 | if (flag == 0)
245 | {
246 | printf("\nelement not found");
247 | }
248 |
249 | }
250 | }
251 |
252 | /*Function to sort the list in ascending order*/
253 |
254 | void sort()
255 | {
256 | struct node *ptr, *nxt;
257 | int temp;
258 |
259 | if (head == NULL)
260 | {
261 | printf("empty linkedlist");
262 | }
263 | else
264 | {
265 | ptr = head;
266 | while (ptr->link != head)
267 | {
268 | nxt = ptr->link;
269 | while (nxt != head)
270 | {
271 | if (nxt != head)
272 | {
273 | if (ptr->data > nxt->data)
274 | {
275 | temp = ptr->data;
276 | ptr->data = nxt->data;
277 | nxt->data = temp;
278 | }
279 | }
280 | else
281 | {
282 | break;
283 | }
284 | nxt = nxt->link;
285 | }
286 | ptr = ptr->link;
287 | }
288 | }
289 | }
290 |
291 | /*Function to update an element at any position the list*/
292 | void update()
293 | {
294 | struct node *ptr;
295 | int search_val;
296 | int replace_val;
297 | int flag = 0;
298 |
299 | if (head == NULL)
300 | {
301 | printf("\n empty list");
302 | }
303 | else
304 | {
305 | printf("enter the value to be edited\n");
306 | scanf("%d", &search_val);
307 | fflush(stdin);
308 | printf("enter the value to be replace\n");
309 | scanf("%d", &replace_val);
310 | ptr = head;
311 | while (ptr->link != head)
312 | {
313 | if (ptr->data == search_val)
314 | {
315 | ptr->data = replace_val;
316 | flag = 1;
317 | break;
318 | }
319 | ptr = ptr->link;
320 | }
321 | if (ptr->data == search_val)
322 | {
323 | ptr->data = replace_val;
324 | flag = 1;
325 | }
326 | if (flag == 1)
327 | {
328 | printf("\nUPdate sucessful");
329 | }
330 | else
331 | {
332 | printf("\n update not successful");
333 | }
334 | }
335 | }
336 |
337 | /*Function to display the elements of the list in reverse order*/
338 |
339 | void rev_traverse(struct node *p)
340 | {
341 | int i = 0;
342 |
343 | if (head == NULL)
344 | {
345 | printf("empty linked list");
346 | }
347 | else
348 | {
349 | if (p->link != head)
350 | {
351 | i = p->data;
352 | rev_traverse(p->link);
353 | printf(" %d", i);
354 | }
355 | if (p->link == head)
356 | {
357 | printf(" %d", p->data);
358 | }
359 | }
360 | }
361 |
--------------------------------------------------------------------------------
/linked_list_algorithms/doubly_linked_list.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | // Making the `size_t` keyword easier to interpret.
8 | typedef size_t size_type;
9 | // A pointer to the nodes in the list
10 | // is defined for easy use in functions.
11 | typedef struct Node* list_iterator;
12 |
13 |
14 | // A structure of `Node` used in the
15 | // doubly linked list for storing keys
16 | // and pointers to neighbouring Nodes.
17 | struct Node
18 | {
19 | int key; // Stores the value to be accessed by the user at runtime.
20 | // Pointers to the next and previous elements in the list.
21 | struct Node *prev, *next;
22 | };
23 |
24 |
25 | // A function that creates and initializes the
26 | // doubly linked list.
27 | list_iterator create_doubly_linked_list(int key)
28 | {
29 |
30 | /*
31 | * Arguments: `key` (int) -> A value to be stored in the list.
32 | * Creates a doubly linked list.
33 | * Returns : `first` (list_iterator) -> A pointer to the first element of list.
34 | */
35 |
36 | // Step 1: Allocate memory to store a variable of type `Node`.
37 | list_iterator first = (list_iterator)malloc(sizeof(struct Node));
38 | // Step 2: Initialize key as provided by the user.
39 | first->key = key;
40 | // Step 3: First element in the list so it doesn't
41 | // have next and prev elements.
42 | first->prev = 0;
43 | first->next = 0;
44 |
45 | // Step 4: Return the pointer to allocated node.
46 | return first;
47 | }
48 |
49 | // Insert a node at the front of the linked list in O(1) time.
50 | list_iterator insert_in_front_of_the_doubly_linked_list(list_iterator first, int key)
51 | {
52 | /*
53 | * Argments: `first` (list_iterator) -> A pointer to the first element in the list.
54 | * Initialize the list using `create_doubly_linked_list()`
55 | * to get this pointer variable
56 | * `key` (int) -> The element to be stored in the list.
57 | * This function is used to insert a Node at the front of the
58 | * doubly linked list. The Node is intialized by the provided value
59 | * of the key and other attributes are initalized according to
60 | * the previously allocated nodes.
61 | * Returns: `new_node` (list_iterator) -> A pointer variable pointing at the new
62 | * Node inserted using this function.
63 | */
64 |
65 | // Step 1: Allocate memory for the new node to be stored.
66 | list_iterator new_node = (list_iterator)malloc(sizeof(struct Node));
67 |
68 | // Step 2: Initialize the key using the key provided by user.
69 | // Step 3: This node has the `next` member as `first`
70 | // which used to be the first Node in the list.
71 | // Step 4: Also, don't forget to add the newly allocated
72 | // node as the previous member of the `first` Node.
73 | // Step 5: The previous member is still `NULL`.
74 | new_node->key = key;
75 | new_node->next = first;
76 | first->prev = new_node;
77 | new_node->prev = 0;
78 |
79 | // Step 6: Return the newly allocated node which will act as the 'first' node in the list.
80 | return new_node;
81 | }
82 |
83 |
84 | // Insert a Node at the end of the linked list in O(1) time.
85 | list_iterator insert_in_end_of_the_doubly_linked_list(list_iterator last, int key)
86 | {
87 | /*
88 | * Argments: `last` (list_iterator) -> A pointer to the last element in the list.
89 | * `key` (int) -> The element to be stored in the list.
90 | * This function is used to insert a Node at the end of the
91 | * doubly linked list. The Node is intialized by the provided value
92 | * of the key and other attributes are initalized according to
93 | * the previously allocated nodes.
94 | * Returns: `new_node` (list_iterator) -> A pointer variable pointing at the new
95 | * Node inserted using this function.
96 | */
97 |
98 | // Step 1: Allocate memory required to store the new node to be inserted in the list.
99 | list_iterator new_node = (list_iterator)malloc(sizeof(struct Node));
100 |
101 | // Step 2: Initialize the key according to the value of key
102 | // provided by the user.
103 | // Step 3: The attribute `prev` will be a pointer to the last node
104 | // in the list. i.e. `last`.
105 | // Step 4: Don't forget to change the `next` attribute of the
106 | // node `last` to `new_node`.
107 | // Step 5: The next member of the list is still NULL.
108 | new_node->key = key;
109 | new_node->prev = last;
110 | last->next = new_node;
111 | new_node->next = 0;
112 |
113 | // Step 6: Return a pointer to the newly allocated element in the list.
114 | return new_node;
115 | }
116 |
117 | // Delete a Node from the end of a linked list in O(1) time.
118 | list_iterator delete_from_the_front_of_the_doubly_linked_list(list_iterator first)
119 | {
120 | /*
121 | * Arguments: `first` (list_iterator) -> A pointer to the first element in the list.
122 | * Deletes the first element in the linked list.
123 | * Returns: `second` (list_iterator) -> A pointer to second element in the list.
124 | */
125 |
126 | // Step 1: Check if there is any other node present in the list.
127 | // If no node is present, delete the `first` pointer and
128 | // hence the whole linked list.
129 | // Return new linked list initialized by key -1.
130 | if(first->next == 0){ free(first);return create_doubly_linked_list(-1); }
131 |
132 | // Step 2: Create a pointer to the next element in the list.
133 | list_iterator second = first->next;
134 |
135 | // Step 3: Delete the `first` pointer pointing to the first element in the list.
136 | free(first);
137 |
138 | // Step 4: Update the `prev` attribute of the second node to NULL.
139 | second->prev = 0;
140 |
141 | // Step 5: Return thr second element.
142 | return second;
143 | }
144 |
145 | // Delete a Node from the end of the linked list in O(1) time.
146 | list_iterator delete_from_the_end_of_the_doubly_linked_list(list_iterator last)
147 | {
148 | /*
149 | * Arguments: `last` (list_iterator) -> A pointer to the last element in the list.
150 | * Deletes the last element in the linked list.
151 | * Returns: `previous` (list_iterator) -> A pointer to second element in the list.
152 | */
153 |
154 | // Step 1: Check if there is any other node present in the list.
155 | // If no node is present, delete the `last` pointer and
156 | // hence the whole linked list.
157 | // Return new linked list initialized by key -1.
158 | if(last->prev == 0){ free(last);return create_doubly_linked_list(-1); }
159 |
160 | // Step 2: Create a pointer to the previous element in the list.
161 | list_iterator previous = last->prev;
162 | // Step 3: Delete the `last` pointer pointing to the last element in the list.
163 | free(last);
164 | // Step 4: Update the `next` attribute of the previous node to NULL.
165 | previous->next = 0;
166 | // Step 5: Return thr previous element.
167 | return previous;
168 | }
169 |
170 | // Deletes a element from the linked list in O(n) time.
171 | list_iterator delete_from_the_doubly_linked_list(list_iterator first, size_type key)
172 | {
173 | /*
174 | * Arguments: `first` (list_iterator) -> A pointer to the first element in the list.
175 | * `key` (size_type) -> A key to be deleted from the linked list.
176 | * Deletes the key from the linked list.
177 | */
178 |
179 | // Step 1: Make a copy of `first` list_iterator.
180 | list_iterator it = first;
181 |
182 | // Step 2: Now, iterate through the list until no more elements are left.
183 | while(it != 0)
184 | {
185 | // Step 3: If the key is found then
186 | if(it->key == key){
187 | // Case 1: It is the first element in the list.
188 | // So, delete it using `delete_from_the_front_of_the_doubly_linked_list`.
189 | if(it == first){
190 | first = delete_from_the_front_of_the_doubly_linked_list(it);
191 | return first; // return the new first pointer to the list.
192 | }
193 | // Case 2: It is the last element in the list.
194 | // So, delete it using `delete_from_the_end_of_the_doubly_linked_list`
195 | if(it->next == 0){
196 | delete_from_the_end_of_the_doubly_linked_list(it);
197 | return first; // return original first pointer.
198 | }
199 |
200 | // Case 3: It is a element somewhere in between the linked list.
201 | list_iterator temp1 = it->prev; // Make a copy of `prev` and `next` nodes of found node.
202 | list_iterator temp2 = it->next;
203 | // Now, the new `next` member of the node `temp1` is the `next` member of `it`.
204 | temp1->next = it->next;
205 | // Similarly, change the pointer `prev` of temp2 to be the next node of `it`.
206 | temp2->prev = it->prev;
207 | free(it); // Delete `it`.
208 | break; // terminate loop as we found the key.
209 | }
210 | // move ahead in the list.
211 | it = it->next;
212 | }
213 | return first; // return the new/original first pointer to the list.
214 | }
215 |
216 | // Searches a element with specified key
217 | list_iterator search_from_start_in_the_doubly_linked_list(list_iterator first, int key)
218 | {
219 | /*
220 | * Arguments: `first` (list_iterator) -> A pointer to the first node in the list.
221 | * `key` (int) -> A key to be retrived during search.
222 | * Search and returns a pointer to the node having the specified key.
223 | * Returns: `temp` (list_iterator) -> A pointer to the found node.
224 | */
225 |
226 | // Make a copy of the first pointer to use
227 | // it during iteration.
228 | list_iterator current_node = first;
229 | // Iterate until key is found and the node pointer is not empty.
230 | while(current_node != 0 && current_node->key != key) current_node = current_node->next; // move ahead in the list
231 | if(current_node != 0) return current_node; // if the node is not empty return.
232 | list_iterator temp = 0; // else return a empty pointer.
233 | return temp;
234 | }
235 |
236 | list_iterator search_from_end_in_the_doubly_linked_list(list_iterator last, int key)
237 | {
238 | list_iterator current_node = last;
239 | while(current_node->key != key && current_node != 0) current_node = current_node->prev;
240 | if(current_node != 0) return current_node;
241 | list_iterator temp = 0;
242 | return temp;
243 | }
244 |
245 | int main()
246 | {
247 | // Creating a doubly linked list.
248 | list_iterator first = create_doubly_linked_list(10);
249 |
250 | // Insert 10 20 and 30 in the front of the doubly linked list.
251 | first = insert_in_front_of_the_doubly_linked_list(first, 10);
252 | first = insert_in_front_of_the_doubly_linked_list(first, 20);
253 | first = insert_in_front_of_the_doubly_linked_list(first, 30);
254 |
255 | // Print the list
256 | list_iterator it = first;
257 | while(it!=0){
258 | printf("%d ", it->key);
259 | it = it->next;
260 | }
261 | }
262 |
--------------------------------------------------------------------------------
/hash_tables.c:
--------------------------------------------------------------------------------
1 | /*
2 | * @author: tirthasheshpatel
3 | * @e-mail: tirthasheshpatel@gmail.com
4 | * Summary: Implemented hash tables and resolved
5 | * collisions using (primarily) chaining
6 | * and open addressing.
7 | */
8 |
9 | // Including necessary libraries.
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | // Defining `M` which is the number of slots
17 | // in our hash table. Because we extract a
18 | // 14-bit least significant bits of the hashed
19 | // key, the maximum size of the slots, hash
20 | // function would hash to, becomes 2^14.
21 | #define M 16385
22 |
23 | // The constant A which is used to perform
24 | // hash by multiplication method is defined
25 | // as `PHI` (conjugate of the golden number)
26 | // as stated in Knuth(2003) and cited in the
27 | // book `Introduction to Algorithms` Section 11.
28 | #define PHI 0.6180339887
29 |
30 | // Making the `size_t` keyword easier to interpret.
31 | typedef size_t size_type;
32 | // A pointer to the nodes in the list
33 | // is defined for easy use in functions.
34 | typedef struct Node* list_iterator;
35 |
36 |
37 | // A structure of `Node` used in the
38 | // doubly linked list for storing keys
39 | // and pointers to neighbouring Nodes.
40 | struct Node
41 | {
42 | int key; // Stores the value to be accessed by the user at runtime.
43 | // Pointers to the next and previous elements in the list.
44 | struct Node *prev, *next;
45 | };
46 |
47 |
48 | // A function that creates and initializes the
49 | // doubly linked list.
50 | list_iterator create_doubly_linked_list(int key)
51 | {
52 |
53 | /*
54 | * Arguments: `key` (int) -> A value to be stored in the list.
55 | * Creates a doubly linked list.
56 | * Returns : `first` (list_iterator) -> A pointer to the first element of list.
57 | */
58 |
59 | // Step 1: Allocate memory to store a variable of type `Node`.
60 | list_iterator first = (list_iterator)malloc(sizeof(struct Node));
61 | // Step 2: Initialize key as provided by the user.
62 | first->key = key;
63 | // Step 3: First element in the list so doesn't
64 | // have next and prev elements.
65 | first->prev = 0;
66 | first->next = 0;
67 |
68 | // Step 4: Return the pointer to allocated node.
69 | return first;
70 | }
71 |
72 | // Insert a node at the front of the linked list in O(1) time.
73 | list_iterator insert_in_front_of_the_doubly_linked_list(list_iterator first, int key)
74 | {
75 | /*
76 | * Argments: `first` (list_iterator) -> A pointer to the first element in the list.
77 | * Initialize the list using `create_doubly_linked_list()`
78 | * to get this pointer variable
79 | * `key` (int) -> The element to be stored in the list.
80 | * This function is used to insert a Node at the front of the
81 | * doubly linked list. The Node is intialized by the provided value
82 | * of the key and other attributes are initalized according to
83 | * the previously allocated nodes.
84 | * Returns: `new_node` (list_iterator) -> A pointer variable pointing at the new
85 | * Node inserted using this function.
86 | */
87 |
88 | // Step 1: Allocate memory for the new node to be stored.
89 | list_iterator new_node = (list_iterator)malloc(sizeof(struct Node));
90 |
91 | // Step 2: Initialize the key using the key provided by user.
92 | // Step 3: This node has the `next` member as `first`
93 | // which used to be the first Node in the list.
94 | // Step 4: Also, don't forget to add the newly allocated
95 | // node as the previous member of the `first` Node.
96 | // Step 5: The previous member is still `NULL`.
97 | new_node->key = key;
98 | new_node->next = first;
99 | first->prev = new_node;
100 | new_node->prev = 0;
101 |
102 | // Step 6: Return the newly allocated node which will act as the 'first' node in the list.
103 | return new_node;
104 | }
105 |
106 |
107 | // Insert a Node at the end of the linked list in O(1) time.
108 | list_iterator insert_in_end_of_the_doubly_linked_list(list_iterator last, int key)
109 | {
110 | /*
111 | * Argments: `last` (list_iterator) -> A pointer to the last element in the list.
112 | * `key` (int) -> The element to be stored in the list.
113 | * This function is used to insert a Node at the end of the
114 | * doubly linked list. The Node is intialized by the provided value
115 | * of the key and other attributes are initalized according to
116 | * the previously allocated nodes.
117 | * Returns: `new_node` (list_iterator) -> A pointer variable pointing at the new
118 | * Node inserted using this function.
119 | */
120 |
121 | // Step 1: Allocate memory required to store the new node to be inserted in the list.
122 | list_iterator new_node = (list_iterator)malloc(sizeof(struct Node));
123 |
124 | // Step 2: Initialize the key according to the value of key
125 | // provided by the user.
126 | // Step 3: The attribute `prev` will be a pointer to the last node
127 | // in the list. i.e. `last`.
128 | // Step 4: Don't forget to change the `next` attribute of the
129 | // node `last` to `new_node`.
130 | // Step 5: The next member of the list is still NULL.
131 | new_node->key = key;
132 | new_node->prev = last;
133 | last->next = new_node;
134 | new_node->next = 0;
135 |
136 | // Step 6: Return a pointer to the newly allocated element in the list.
137 | return new_node;
138 | }
139 |
140 | // Delete a Node from the end of a linked list in O(1) time.
141 | list_iterator delete_from_the_front_of_the_doubly_linked_list(list_iterator first)
142 | {
143 | /*
144 | * Arguments: `first` (list_iterator) -> A pointer to the first element in the list.
145 | * Deletes the first element in the linked list.
146 | * Returns: `second` (list_iterator) -> A pointer to second element in the list.
147 | */
148 |
149 | // Step 1: Check if there is any other node present in the list.
150 | // If no node is present, delete the `first` pointer and
151 | // hence the whole linked list.
152 | // Return new linked list initialized by key -1.
153 | if(first->next == 0){ free(first);return create_doubly_linked_list(-1); }
154 |
155 | // Step 2: Create a pointer to the next element in the list.
156 | list_iterator second = first->next;
157 |
158 | // Step 3: Delete the `first` pointer pointing to the first element in the list.
159 | free(first);
160 |
161 | // Step 4: Update the `prev` attribute of the second node to NULL.
162 | second->prev = 0;
163 |
164 | // Step 5: Return thr second element.
165 | return second;
166 | }
167 |
168 | // Delete a Node from the end of the linked list in O(1) time.
169 | list_iterator delete_from_the_end_of_the_doubly_linked_list(list_iterator last)
170 | {
171 | /*
172 | * Arguments: `last` (list_iterator) -> A pointer to the last element in the list.
173 | * Deletes the last element in the linked list.
174 | * Returns: `previous` (list_iterator) -> A pointer to second element in the list.
175 | */
176 |
177 | // Step 1: Check if there is any other node present in the list.
178 | // If no node is present, delete the `last` pointer and
179 | // hence the whole linked list.
180 | // Return new linked list initialized by key -1.
181 | if(last->prev == 0){ free(last);return create_doubly_linked_list(-1); }
182 |
183 | // Step 2: Create a pointer to the previous element in the list.
184 | list_iterator previous = last->prev;
185 | // Step 3: Delete the `last` pointer pointing to the last element in the list.
186 | free(last);
187 | // Step 4: Update the `next` attribute of the previous node to NULL.
188 | previous->next = 0;
189 | // Step 5: Return thr previous element.
190 | return previous;
191 | }
192 |
193 | // Deletes a element from the linked list in O(n) time.
194 | list_iterator delete_from_the_doubly_linked_list(list_iterator first, size_type key)
195 | {
196 | /*
197 | * Arguments: `first` (list_iterator) -> A pointer to the first element in the list.
198 | * `key` (size_type) -> A key to be deleted from the linked list.
199 | * Deletes the key from the linked list.
200 | */
201 |
202 | // Step 1: Make a copy of `first` list_iterator.
203 | list_iterator it = first;
204 |
205 | // Step 2: Now, iterate through the list until no more elements are left.
206 | while(it != 0)
207 | {
208 | // Step 3: If the key is found then
209 | if(it->key == key){
210 | // Case 1: It is the first element in the list.
211 | // So, delete it using `delete_from_the_front_of_the_doubly_linked_list`.
212 | if(it == first){
213 | first = delete_from_the_front_of_the_doubly_linked_list(it);
214 | return first; // return the new first pointer to the list.
215 | }
216 | // Case 2: It is the last element in the list.
217 | // So, delete it using `delete_from_the_end_of_the_doubly_linked_list`
218 | if(it->next == 0){
219 | delete_from_the_end_of_the_doubly_linked_list(it);
220 | return first; // return original first pointer.
221 | }
222 |
223 | // Case 3: It is a element somewhere in between the linked list.
224 | list_iterator temp1 = it->prev; // Make a copy of `prev` and `next` nodes of found node.
225 | list_iterator temp2 = it->next;
226 | // Now, the new `next` member of the node `temp1` is the `next` member of `it`.
227 | temp1->next = it->next;
228 | // Similarly, change the pointer `prev` of temp2 to be the next node of `it`.
229 | temp2->prev = it->prev;
230 | free(it); // Delete `it`.
231 | break; // terminate loop as we found the key.
232 | }
233 | // move ahead in the list.
234 | it = it->next;
235 | }
236 | return first; // return the new/original first pointer to the list.
237 | }
238 |
239 | // Searches a element with specified key
240 | list_iterator search_from_start_in_the_doubly_linked_list(list_iterator first, int key)
241 | {
242 | /*
243 | * Arguments: `first` (list_iterator) -> A pointer to the first node in the list.
244 | * `key` (int) -> A key to be retrived during search.
245 | * Search and returns a pointer to the node having the specified key.
246 | * Returns: `temp` (list_iterator) -> A pointer to the found node.
247 | */
248 |
249 | // Make a copy of the first pointer to use
250 | // it during iteration.
251 | list_iterator current_node = first;
252 | // Iterate until key is found and the node pointer is not empty.
253 | while(current_node != 0 && current_node->key != key) current_node = current_node->next; // move ahead in the list
254 | if(current_node != 0) return current_node; // if the node is not empty return.
255 | list_iterator temp = 0; // else return a empty pointer.
256 | return temp;
257 | }
258 |
259 | list_iterator search_from_end_in_the_doubly_linked_list(list_iterator last, int key)
260 | {
261 | list_iterator current_node = last;
262 | while(current_node->key != key && current_node != 0) current_node = current_node->prev;
263 | if(current_node != 0) return current_node;
264 | list_iterator temp = 0;
265 | return temp;
266 | }
267 |
268 |
269 | // A function to find the Hash Code of a integer key
270 | // using the division method.
271 | // h(k) = k modulo m;
272 | // where m is the size of the hash table.
273 | size_type hash_by_division_method(size_type key)
274 | {
275 | /*
276 | * Arguments: `key` (size_type) -> A integer key to be hashed.
277 | * Hashes the given key using the division method for hashing.
278 | * Returns: (size_type) -> Hashed key.
279 | */
280 | return key%M;
281 | }
282 |
283 | // A function to find the hash code of the
284 | // key using multiplication method proposed
285 | // in the book `Introduction to algorithms`.
286 | size_type hash_by_multiplication_method(size_type key)
287 | {
288 | /*
289 | * Arguments: `key` (size_type) -> A integer key to be Hashed.
290 | * Hashes and returns the entered key using the multiplication method.
291 | * Returns : (size_type) -> 14-bit Hash Code of the given key.
292 | */
293 |
294 |
295 | // Set the bit-width 32 because at the end
296 | // we are going to multiply two 32 bit integers
297 | // to get a 64 bit long integer. Using 64 bit
298 | // integer may lead to possible loss of data.
299 | long long w = 4294967296; // Bit-width w = 2^32
300 |
301 | // Now, we have a constant A = PHI, that we
302 | // need to convert in the form ` s / w `
303 | // such that `s` is the nearest integer that can
304 | // be represented as ` A * w `. As
305 | // `A = PHI`, we have `s = floor(PHI * w)`.
306 | // Then, we multiply the key with obtained `s`
307 | // => `l = key * s`
308 | // Now, we have `l = w * r1 + r0` where
309 | // `r0` is the fractional part of `l`.
310 | // We extract 14 most significant bits of `r0`
311 | // to get our 14 bit hash key.
312 | return ( ( ( (size_type)fmod((key*floor(PHI*w)),w) ) >> (32-14) ) );
313 | }
314 |
315 | // A function to find Hash Code of the key
316 | // using linear probing. Used by hash tables
317 | // in which collision is resolved by open addressing.
318 | size_type open_address_linear_probing(size_type key, size_type probe)
319 | {
320 | /*
321 | * Arguments: `key` (size_type) -> Key to be hashed
322 | * `probe` (size_type) -> Probe number assigned to the key.
323 | * Hashes the provided key using Linear Probing method
324 | * used to resolve collisions in hash tables using
325 | * open addressing. The equation used to hash the key is:
326 | * `h(k) = ( h'(k) + probe ) modulo `M` where `k` = key
327 | * `h` = hash function, `h'` = other hash function, `M` = slots in the hash table
328 | * and `probe` = probe number of key `k`.
329 | * Returns: (size_type) -> Hash Code of key.
330 | */
331 | return (hash_by_multiplication_method(key) + probe)%M;
332 | }
333 |
334 | // A function to find the hash code of a key
335 | // using Quadratic Probing. Used by hash tables
336 | // in which collision is resolved through
337 | // open addressing.
338 | size_type open_address_quadratic_probing(size_type key, size_type probe)
339 | {
340 | /*
341 | * Arguments: `key` (size_type) -> Key to be hashed.
342 | * `probe` (size_type) -> Probe number assigned to the key.
343 | * Hashes the provided key using Quadratic Probing method
344 | * used to resolve collisions in hash tables using
345 | * open addressing. The equation used to hash the key is:
346 | * `h(k) = ( h'(k) + a*(probe) + b*(probe^2)) modulo M`
347 | * where `M` = Slots in the table, `k` = Key to be hashed,
348 | * `h'` = hash function, `a` and `b` = arbitary constants,
349 | * `probe` = Probe number of key `k`.
350 | * Returns: (size_type) -> Hash Code of the key.
351 | */
352 | return (hash_by_multiplication_method(key) + 4*probe + 5*probe*probe)%M;
353 | }
354 |
355 | // A function to find the hash of a key
356 | // using Double Hashing method used to
357 | // resolve the collisions in hash tables.
358 | size_type open_address_double_hashing(size_type key, size_type probe)
359 | {
360 | /*
361 | * Arguments: `key` (size_type) -> Key to be hashed.
362 | * `probe` (size_type) -> Probe number assigned to the key.
363 | * Hashes the provided key using two other hash functions
364 | * used to resolve collisions by providing the property of
365 | * almost random behaviour. It is used in hash tables
366 | * using Open Addressing to resolve collisions.
367 | * Returns: (size_type) -> Hash Code of the key.
368 | */
369 | return ( hash_by_multiplication_method(key) + probe*hash_by_division_method(key) )%M;
370 | }
371 |
372 | // A function that inserts a key into the hash table in O(1) time.
373 | void insert_in_hash_table(list_iterator *table, size_type key)
374 | {
375 | /*
376 | * Arguments: `table` (list_iterator) -> A hash table with slots M.
377 | * `key` (size_type) -> A key to be stored in the table.
378 | * Stores the entered key into the hash table in O(1) time.
379 | * The hash table resolves collisions through `Chaining`.
380 | * So, the keys are stored in a doubly linked list.
381 | * Returns: -
382 | */
383 |
384 | // Check if key to be stored is valid.
385 | if(key <= 0) return;
386 |
387 | // Find the 14-bit hash code of the key `key` using multiplication method.
388 | size_type hash = hash_by_multiplication_method(key);
389 |
390 | // The hash code of the key is now our new key or the
391 | // index where the original key is to be stored
392 | // in the hash tables.
393 | if(table[hash]->key == -1) // Check if the slot is empty
394 | {
395 | // If empty, store the key in the first node of the doubly linked list.
396 | table[hash]->key = key;
397 | table[hash]->next = 0; // No next and previous node is present.
398 | table[hash]->prev = 0;
399 | return;
400 | }
401 |
402 | // If the slot is not empty, add a node to the list and store the key there.
403 | table[hash] = insert_in_front_of_the_doubly_linked_list(table[hash], key);
404 | return;
405 | }
406 |
407 |
408 | // Delete a key from the slot of the table in a average-case time O(ALPHA)
409 | // where ALPHA = load factor = N/M. N = No of keys to be inserted, M = Slots present.
410 | void delete_from_hash_table(list_iterator *table, size_type key)
411 | {
412 | // Find the hash code of a key `key` using Multiplication Method.
413 | size_type hash = hash_by_multiplication_method(key);
414 | // Delete element from the doubly linked
415 | // list present at the hashed slot.
416 | // This function runs in linear time by first searching
417 | // for the key and deleting the found node if any.
418 | table[hash] = delete_from_the_doubly_linked_list(table[hash], key);
419 | return;
420 | }
421 |
422 | // Searches for a key in the hash table in linear time.
423 | list_iterator search_in_hash_table(list_iterator *table, size_type key)
424 | {
425 | /*
426 | * Arguments: `table` (list_iterator) -> An object of Hash Table.
427 | * `key` (size_type) -> A key to be stored in the hash table.
428 | * Hashes the key and searches for the original key in the hashed slot
429 | * using search function of doubly linked list.
430 | * Returns : `element` (list_iterator) -> The found node where the key is present.
431 | */
432 |
433 | // Hash the key.
434 | size_type hash = hash_by_multiplication_method(key);
435 | // Search in the doubly linked list from the start.
436 | list_iterator element = search_from_start_in_the_doubly_linked_list(table[hash], key);
437 | return element; // return element if found otherwise return empty pointer.
438 | }
439 |
440 | int main()
441 | {
442 | int key = 123456;
443 | printf("%lu\n", hash_by_multiplication_method(key));
444 | }
445 |
--------------------------------------------------------------------------------
/cpp_algorithms/sorting_and_searching_in_cpp/Algorithms.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * @author: tirthasheshpatel@gmail.com
3 | * @github: tirthasheshpatel@github.com
4 | * All the algorithms from CLRS Section 1 are implemented except Strassen's Algorithm.
5 | * Sorting algorithms implemented : 1.) Insertion Sort
6 | 2.) Heap Sort
7 | 3.) Quick Sort
8 | 4.) Randomized Quick Sort
9 | 5.) Counting Sort
10 | 6.) Merge Sort
11 | 7.) Selection Sort
12 | 8.) Bubble Sort
13 | * Search algorithms impletmented : 1.) Linear Search
14 | 2.) Binary Search
15 | * Generic algorithms implemented : 1.) nrand
16 | 2.) swap
17 | 3.) invertion (brute force)
18 | 4.) count_invertions (devide and concour)
19 | 5.) max_subarray_brute_force (brute force)
20 | 6.) max_subarray (devide and concour)
21 | 7.) max_subarray_linear (linear method)
22 | 8.) Inflix to Reverse Polish // Not implemented Yet!
23 | * Data Structures Implemented : 1.) Heap
24 | 2.) Priority Queue
25 | */
26 |
27 | // Including dependencies
28 | #include
29 | #include
30 | #include
31 | #include // std::domain_error
32 | #include // rand(), RAND_MAX
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | constexpr auto MAX = 10000;
41 |
42 | typedef size_t size_type;
43 |
44 | // importing required functions
45 | using std::domain_error;
46 | using std::rand;
47 | using std::cout;
48 | using std::cin;
49 | using std::endl;
50 | using std::chrono::high_resolution_clock;
51 | using std::chrono::milliseconds;
52 | using std::chrono::nanoseconds;
53 | using std::chrono::duration_cast;
54 | using std::sort;
55 | using std::make_heap;
56 | using std::sort_heap;
57 | using std::is_sorted;
58 | using std::max_element;
59 |
60 | // Subarray class specially designed for maximum subarray problem
61 | struct subarray
62 | {
63 | int lb;
64 | int ub;
65 | int sum;
66 | };
67 |
68 | /*
69 | * Arguments: n(int)
70 | * n is the upperbound of the randomly generated numbers
71 | * Returns: random number r - int
72 | */
73 | int nrand(int n)
74 | {
75 | if (n <= 0 || n > RAND_MAX)
76 | throw domain_error("Argument to nrand is out of range");
77 |
78 | const int bucket_size = RAND_MAX / n;
79 | int r;
80 |
81 | do r = rand() / bucket_size;
82 | while (r >= n);
83 |
84 | return r;
85 | }
86 |
87 | /*
88 | * Arguments: a(int, float), b(int, float)
89 | * Swaps a and b inplace.
90 | * Time: O(1)
91 | */
92 | template
93 | void swap(T* a, T* b)
94 | {
95 | T temp = *a;
96 | *a = *b;
97 | *b = temp;
98 | }
99 |
100 | /*
101 | * Arguments: arr(int*, float*), start(int), end(int), num(int float)
102 | * Searches for num in arr from start to end
103 | * Returns: index of num if found else -1. - int
104 | * Time: theta(lg (end-start))
105 | */
106 | template
107 | int binary_search(T arr[], int start, int end, T num)
108 | {
109 | // If size decreased to zero means num is not
110 | // present in arr. Hence return -1.
111 | if (start >= end) return -1;
112 |
113 | // otherwise devide the arrar in smaller equal
114 | // parts until we don't find num.
115 | int mid = (start + end) / 2;
116 | if (num == arr[mid]) return mid + 1;
117 | if (num > arr[mid]) return binary_search(arr, mid, end, num);
118 | else return binary_search(arr, start, mid, num);
119 | }
120 |
121 | /*
122 | * Arguments: arr(int*, float*), n(int, size_t), num(int, float)
123 | * Searches for num in the array arr
124 | * Returns: index of first occerence of element if found else returns -1. - int
125 | * Time: O(n)
126 | */
127 | template
128 | int linear_search_1(T arr[], int n, T num)
129 | {
130 | int ind = -2;
131 |
132 | // Perform linear search
133 | for (int i = 0; i < n; i++) {
134 | if (arr[i] == num) { ind = i; break; }
135 | }
136 |
137 | return ind + 1;
138 | }
139 |
140 | /*
141 | * Arguments: arr(int*, float*), start(int), end(int)
142 | * Sorts array arr inplace from start to end
143 | * Time: O((end-start)^2)
144 | */
145 | template
146 | void insertion_sort(T arr[], int start, int end)
147 | {
148 | for (int i = start; i < end; i++) {
149 | // pin current element of array
150 | T key = arr[i];
151 | int j = i - 1;
152 | // sort subarray from start to i-1.
153 | while (j >= start && key < arr[j]) {
154 | arr[j + 1] = arr[j];
155 | j--;
156 | }
157 | // Insert our key at resulting index.
158 | arr[j + 1] = key;
159 | }
160 | }
161 |
162 |
163 | // Functions to get the attributes of a Heap
164 | int left(int i) { return 2 * i + 1; }
165 | int right(int i) { return 2 * i + 2; }
166 | int parent(int i) { return ceil((float)i / 2) - 1; }
167 |
168 | /*
169 | * Arguments: arr(int*, float*), i(int), n(size_t)
170 | * Element i of the array arr of size n is placed in
171 | a manner that it satisfies the max heap property
172 | arr[i] > arr[2*i+1] and arr[i] > arr[2*i+2]
173 | * Time: O(lg n)
174 | */
175 | template
176 | void max_heapify(T arr[], int i, int n)
177 | {
178 | int l = left(i);
179 | int r = right(i);
180 | int largest;
181 | if (l < n && arr[l] > arr[i])
182 | largest = l;
183 | else largest = i;
184 | if (r < n && arr[r] > arr[largest])
185 | largest = r;
186 | if (largest != i) {
187 | swap(&arr[i], &arr[largest]);
188 | max_heapify(arr, largest, n);
189 | }
190 | }
191 |
192 | /*
193 | * Arguments: arr(int*, float*), i(int), n(size_t)
194 | * Element i of the array arr of size n is placed in
195 | a manner that it satisfies the min heap property
196 | arr[i] < arr[2*i+1] and arr[i] < arr[2*i+2]
197 | * Time: O(lg n)
198 | */
199 | template
200 | void min_heapify(T arr[], int i, int n)
201 | {
202 | int l = left(i);
203 | int r = right(i);
204 | int lowest;
205 | if (l < n && arr[l] < arr[i])
206 | lowest = l;
207 | else lowest = i;
208 | if (r < n && arr[r] < arr[lowest])
209 | lowest = r;
210 | if (lowest != i) {
211 | swap(&arr[i], &arr[lowest]);
212 | min_heapify(arr, lowest, n);
213 | }
214 | }
215 |
216 | /*
217 | * Arguments: arr(int*, float*), n(int)
218 | * Builds a max heap from a arrar arr of sie n.
219 | * Time: O(n)
220 | */
221 | template
222 | void build_max_heap(T arr[], int n)
223 | {
224 | for (int i = floor(n / 2); i >= 0; i--)
225 | {
226 | max_heapify(arr, i, n);
227 | }
228 | }
229 |
230 | /*
231 | * Arguments: arr(int*, float*), n(int)
232 | * Builds a min heap from a arrar arr of sie n.
233 | * Time: O(n)
234 | */
235 | template
236 | void build_min_heap(T arr[], int n)
237 | {
238 | for (int i = floor(n / 2); i >= 0; i--)
239 | {
240 | min_heapify(arr, i, n);
241 | }
242 | }
243 |
244 | /*
245 | * Arguments: arr(int*, float*)
246 | * Returns the maximum element in the heap arr.
247 | * Time: O(1)
248 | * Returns: max - int, float
249 | */
250 | template
251 | T heap_max(int arr[]) {
252 | return arr[0];
253 | }
254 |
255 | /*
256 | * Arguments: arr(nt*, float*), n(size_t)
257 | * Extracts maximum element from heap arr of size n
258 | and pushes the max element to the end
259 | of the heap. All the remaining elements
260 | of the array are again converted into heap.
261 | * Returns: max - int, float
262 | * Time: theta(lg n)
263 | */
264 | template
265 | T heap_extract_max(T arr[], int n)
266 | {
267 | if (n < 1) throw domain_error("heap underflow");
268 | T max = arr[0];
269 | swap(&arr[0], &arr[n - 1]);
270 | n--;
271 | max_heapify(arr, 0, n);
272 | return max;
273 | }
274 |
275 | /*
276 | * Arguments: arr(int*, float*), i(int), key(int, float)
277 | * Replaces current key at index i of heap arr by the
278 | provided key.
279 | * Time: O(lg n)
280 | */
281 | template
282 | void heap_increase_key(T arr[], int i, T key)
283 | {
284 | if (key < arr[i]) throw domain_error("new key less than the current key.");
285 | arr[i] = key;
286 | while (i > 0 && arr[i] > arr[parent(i)]) {
287 | // swap(&arr[i], &arr[parent(i)]);
288 | arr[i] = arr[parent(i)];
289 | i = parent(i);
290 | }
291 | arr[i] = key;
292 | }
293 |
294 | /*
295 | * Arguments: arr(int*, float*), n(size_t), key(int, float)
296 | * Inserts key in the heap of size n.
297 | * Note: The array should be dynamic for easy memory allocation.
298 | * Time: O(lg n)
299 | */
300 | template
301 | void max_heap_insert(T arr[], int n, T key)
302 | {
303 | n++;
304 | arr[n] = (T)0;
305 | heap_increase_key(arr, n, key);
306 | }
307 |
308 | /*
309 | * Arguments: arr(int*, float*), n(size_t), i(int)
310 | * Deletes the element at index i of heap
311 | arr of size n.
312 | * Time: O(lg n)
313 | */
314 | template
315 | void max_heap_delete(T arr[], int n, int i)
316 | {
317 | swap(&arr[i], &arr[n - 1]);
318 | max_heapify(arr, i, n - 1);
319 | }
320 |
321 | /*
322 | * Arguments: arr(int*, float*), n(size_t)
323 | * Sorts a array arr of size n inplace.
324 | * Time: theta(n lg n)
325 | */
326 | template
327 | void heap_sort(T arr[], int n)
328 | {
329 | build_max_heap(arr, n);
330 | int heap_size = n;
331 | for (int i = n - 1; i >= 0; i--)
332 | {
333 | swap(&arr[0], &arr[i]);
334 | heap_size--;
335 | max_heapify(arr, 0, heap_size);
336 | }
337 | }
338 |
339 |
340 | template
341 | int partition(T arr[], int start, int end)
342 | {
343 | T pivot = arr[end];
344 | int i = start - 1;
345 | for (int j = start; j < end; j++) {
346 | if (arr[j] <= pivot) {
347 | i++;
348 | swap(&arr[i], &arr[j]);
349 | }
350 | }
351 | swap(&arr[i + 1], &arr[end]);
352 | return i + 1;
353 | }
354 |
355 | template
356 | int randomized_partition(T arr[], int start, int end)
357 | {
358 | int i = rand() % (end - start) + start;
359 | swap(&arr[end], &arr[i]);
360 | return partition(arr, start, end);
361 | }
362 |
363 | template
364 | void quick_sort(T arr[], int n, int start, int end)
365 | {
366 | if (end - start <= 30) return;
367 | if (end > start) {
368 | int div = partition(arr, start, end);
369 | quick_sort(arr, n, start, div - 1);
370 | quick_sort(arr, n, div + 1, end);
371 | }
372 | if (end - start == n) insertion_sort(arr, 0, n);
373 | }
374 |
375 | template
376 | void randomized_quick_sort(T arr[], int n, int start, int end)
377 | {
378 | if (end - start <= 20) return;
379 | if (end > start) {
380 | int div = randomized_partition(arr, start, end);
381 | randomized_quick_sort(arr, n, start, div - 1);
382 | randomized_quick_sort(arr, n, div + 1, end);
383 | }
384 | if (end - start == n) insertion_sort(arr, 0, n);
385 | }
386 |
387 | void counting_sort(int arr[], int aux[], int n)
388 | {
389 | int k = *max_element(arr, arr + n);
390 | int* counts = new int[k + 1];
391 | for (int i = 0; i < k + 1; i++) counts[i] = 0;
392 | for (int i = 0; i < n; i++) {
393 | counts[arr[i]]++;
394 | }
395 | for (int i = 1; i < k + 1; i++) {
396 | counts[i] += counts[i - 1];
397 | }
398 | for (int i = n - 1; i >= 0; i--) {
399 | aux[counts[arr[i]] - 1] = arr[i];
400 | counts[arr[i]]--;
401 | }
402 | delete[] counts;
403 | }
404 |
405 | /*
406 | * Arguments: arr(int*, float*), start(int), mid(int), end(int)
407 | * Merges two subarrays, one from start to mid and the other from
408 | mid+1 to end, such that resulting array arr is sorted inplace
409 | from start to end.
410 | * Time: theta((end-start))
411 | */
412 | template
413 | void merge(T arr[], int start, int mid, int end)
414 | {
415 | // use insertion sort for subarray of size <= 40
416 | if (end - start <= 40) insertion_sort(arr, start, end + 1);
417 |
418 | else {
419 | // initialize subarrays
420 | int arr_1_size = mid - start + 1;
421 | int arr_2_size = end - mid;
422 | T* arr1 = new T[arr_1_size];
423 | T* arr2 = new T[arr_2_size];
424 |
425 | // Insert elements from arr to those subarrays
426 | for (int i = start, j = 0; i <= mid; i++, j++) arr1[j] = arr[i];
427 | for (int i = mid + 1, j = 0; i <= end; i++, j++) arr2[j] = arr[i];
428 |
429 | // Start merging the subarrays maintaing
430 | // the chronological order of the elements.
431 | int i = 0, j = 0, k = start;
432 | while (i < arr_1_size && j < arr_2_size) {
433 | if (arr1[i] <= arr2[j]) arr[k++] = arr1[i++];
434 | else arr[k++] = arr2[j++];
435 | }
436 | while (i < arr_1_size) arr[k++] = arr1[i++];
437 | while (j < arr_2_size) arr[k++] = arr2[j++];
438 |
439 | delete[] arr1;
440 | delete[] arr2;
441 | }
442 |
443 | }
444 |
445 | /*
446 | * Arguments: arr(int*, float*), start(int), end(int)
447 | * Sorts array arr inplace from start to end
448 | * Time: theta(nk + nk * lg n/k) | n = end - start and k = 40
449 | */
450 | template
451 | void merge_sort(T arr[], int start, int end)
452 | {
453 | if (end > start) {
454 | int mid = (end + start) / 2;
455 | // Uncomment below line for debugging.
456 | // cout << start << " " << mid << " " << end << endl;
457 | merge_sort(arr, start, mid);
458 | merge_sort(arr, mid + 1, end);
459 | merge(arr, start, mid, end);
460 | }
461 | return;
462 | }
463 |
464 | /*
465 | * Arguments: arr(int*, float*), n(size_t)
466 | * Sorts array arr of size n inplace.
467 | * Time: theta(n^2)
468 | */
469 | template
470 | void bubble_sort(T arr[], int n)
471 | {
472 | for (int i = 0; i < n - 1; i++) {
473 | for (int j = i + 1; j < n; j++) {
474 | if (arr[i] > arr[j]) swap(&arr[i], &arr[j]);
475 | }
476 | }
477 | }
478 |
479 | /*
480 | * Arguments: arr(int*, float*), n(size_t)
481 | * Sorts array arr of size n inplace.
482 | * Time: O(n^2)
483 | */
484 | template
485 | void selection_sort(T arr[], int n)
486 | {
487 | T min = arr[0], ind = 0;
488 | for (int j = 0; j < n; j++) {
489 | min = arr[j]; ind = j;
490 | for (int i = j; i < n; i++) {
491 | if (arr[i] < min) { min = arr[i]; ind = i; }
492 | }
493 | if (ind != j) swap(&arr[ind], &arr[j]);
494 | }
495 | }
496 |
497 | /*
498 | * Arguments: arr(int*, float*), start(int), end(int)
499 | * Counts the number of invertions in a array arr from start to end
500 | * Returns: number of invertions - int
501 | * Time: O((end-start)^2)
502 | */
503 | template
504 | int invertion(T arr[], int start, int end) {
505 | int invertions = 0;
506 |
507 | // Check every possible combination and
508 | // count the number of invertions.
509 | for (int i = start; i < end - 1; i++) {
510 | for (int j = i + 1; j < end; j++) {
511 | if (arr[i] > arr[j]) invertions++;
512 | }
513 | }
514 |
515 | return invertions;
516 | }
517 |
518 | /*
519 | * Arguments: arr(int*), start(int), mid(int), end(int)
520 | * Counts the invertions in two sorted subarrays of arr
521 | , one from start to mid and the other from mid+1 to end.
522 | * Returns: number of invertions - int
523 | * Time: theta(end-start)
524 | */
525 | int merge_invertions(int arr[], int start, int mid, int end)
526 | {
527 | int l_size = mid - start + 1;
528 | int r_size = end - mid;
529 | int* l = new int[l_size];
530 | int* r = new int[r_size];
531 | for (int i = start, j = 0; i <= mid; i++, j++) l[j] = arr[i];
532 | for (int i = mid + 1, j = 0; i <= end; i++, j++) r[j] = arr[i];
533 | int i = 0, j = 0, invertions = 0, k = start;
534 | while (i < l_size && j < r_size) {
535 | if (l[i] > r[j]) {
536 | invertions += l_size - i;
537 | arr[k++] = r[j++];
538 | }
539 | else arr[k++] = l[i++];
540 | }
541 | while (i < l_size) arr[k++] = l[i++];
542 | while (j < r_size) arr[k++] = r[j++];
543 |
544 | delete[] l;
545 | delete[] r;
546 |
547 | return invertions;
548 | }
549 |
550 | /*
551 | * Arguments: arr(int*), start(int), end(int)
552 | * Counts the number of invertions of array
553 | arr from start to end.
554 | * Returns: number of invertions - int
555 | * Time: theta(n lg n) | n = end - start
556 | */
557 | int count_invertions(int arr[], int start, int end)
558 | {
559 | int invertions = 0;
560 | if (end > start) {
561 | int mid = (start + end) / 2;
562 | invertions += count_invertions(arr, start, mid);
563 | invertions += count_invertions(arr, mid + 1, end);
564 | invertions += merge_invertions(arr, start, mid, end);
565 | }
566 | return invertions;
567 | }
568 |
569 | /*
570 | * Arguments: arr(int*), n(size_t)
571 | * Finds a pair of days yielding maximum
572 | profit in stock market given an array
573 | arr of prices of stocks of each day.
574 | * Returns: subarray with maximum sum - subarray
575 | * Time: theta(n^2)
576 | */
577 | subarray max_subarray_brute_force(int arr[], int n)
578 | {
579 | subarray s;
580 | int p, lb = 0, ub = 1;
581 | int mp = arr[ub] - arr[lb];
582 | for (int i = 0; i < n - 1; i++) {
583 | for (int j = i + 1; j < n; j++) {
584 | p = arr[j] - arr[i];
585 | if (p > mp) {
586 | mp = p;
587 | lb = i;
588 | ub = j;
589 | }
590 | }
591 | }
592 | s.lb = lb;
593 | s.ub = ub;
594 | s.sum = mp;
595 | return s;
596 | }
597 |
598 | /*
599 | * Arguments: arr(int*), start(int), mid(int), end(int)
600 | * Finds a subarray maving maximum sum crossing through
601 | the mid index of the arr.
602 | * Returns: subarray with maximum crossing sum - subarray
603 | * Time: theta(end-start)
604 | */
605 | subarray max_crossing_subarray(int arr[], int start, int mid, int end)
606 | {
607 | subarray sa;
608 | int lsum = arr[mid];
609 | sa.lb = mid;
610 | int sum = 0;
611 | for (int i = mid; i >= start; i--) {
612 | sum += arr[i];
613 | if (sum > lsum) {
614 | lsum = sum;
615 | sa.lb = i;
616 | }
617 | }
618 | int rsum = arr[mid + 1];
619 | sa.ub = mid + 1;
620 | sum = 0;
621 | for (int i = mid + 1; i <= end; i++) {
622 | sum += arr[i];
623 | if (sum > rsum) {
624 | rsum = sum;
625 | sa.ub = i;
626 | }
627 | }
628 | sa.sum = lsum + rsum;
629 | return sa;
630 | }
631 |
632 | /*
633 | * Arguments: arr(int*), start(int), end(int)
634 | * Finds a subarray of arrar arr having maximum
635 | sum from start to end.
636 | * Returns: subarray with maximum sum - subarray
637 | * Time: theta(n lg n) | n = end-start
638 | */
639 | subarray max_subarray(int arr[], int start, int end)
640 | {
641 | if (start == end) {
642 | subarray bc;
643 | bc.lb = start;
644 | bc.ub = end;
645 | bc.sum = arr[start];
646 | return bc;
647 | }
648 | else {
649 | int mid = (start + end) / 2;
650 | subarray l = max_subarray(arr, start, mid);
651 | subarray r = max_subarray(arr, mid + 1, end);
652 | subarray c = max_crossing_subarray(arr, start, mid, end);
653 | if (l.sum >= r.sum && l.sum >= c.sum) return l;
654 | else if (r.sum >= l.sum && r.sum >= c.sum) return r;
655 | else return c;
656 | }
657 | }
658 |
659 | /*
660 | * Arguments: arr(int*), n(size_t)
661 | * Finds a subarray of array arr of size n whose
662 | sum is maximum of all possible subarrays.
663 | * Returns: subarray with maximum sum - subarray
664 | * Time: theta(n)
665 | */
666 | subarray max_subarray_linear(int arr[], int n)
667 | {
668 | subarray res;
669 | res.sum = arr[0];
670 | int sum = 0;
671 |
672 | for (int i = 0, j = 0; i < n && j < n; j++) {
673 | sum += arr[j];
674 | if (sum > res.sum) {
675 | res.sum = sum;
676 | res.lb = i;
677 | res.ub = j;
678 | }
679 | if (sum < 0) {
680 | sum = 0;
681 | i = j + 1;
682 | }
683 | }
684 |
685 | return res;
686 | }
687 |
688 | /*
689 | * A function to play around with the sorting algorithms present.
690 | */
691 | void sorting_playground()
692 | {
693 | srand(time(0));
694 | int arr1[300000], arr2[300000], arr3[300000], arr3_aux[300000];
695 | for (int i = 0; i < 300000; i++) arr1[i] = nrand(10000);
696 | for (int i = 0; i < 300000; i++) { arr2[i] = arr1[i]; arr3[i] = arr1[i]; }
697 | auto start = high_resolution_clock::now();
698 | sort(arr1, arr1 + 300000);
699 | auto end = high_resolution_clock::now();
700 | cout << "Sorting Method : " << "Time in milliseconds" << endl << endl;
701 | cout << "C++ std sort : " << duration_cast(end - start).count() << endl;
702 | start = high_resolution_clock::now();
703 | quick_sort(arr2, 300000, 0, 300000 - 1);
704 | end = high_resolution_clock::now();
705 | cout << "quick_sort : " << duration_cast(end - start).count() << endl;
706 | start = high_resolution_clock::now();
707 | counting_sort(arr3, arr3_aux, 300000);
708 | end = high_resolution_clock::now();
709 | cout << "counting_sort : " << duration_cast(end - start).count() << endl;
710 | }
711 |
712 | void search_playground()
713 | {
714 | srand(time(0));
715 | int arr[200000];
716 | for (int i = 0; i < 200000; i++) arr[i] = nrand(10000);
717 | sort(arr, arr + 200000);
718 | int num = 1000;
719 | auto start = high_resolution_clock::now();
720 | int ind = binary_search(arr, 0, 200000 - 1, num);
721 | auto end = high_resolution_clock::now();
722 | cout << "Binary Search: " << duration_cast(end - start).count() << " Answer: " << ind << endl;
723 | start = high_resolution_clock::now();
724 | int ind2 = linear_search_1(arr, 200000, num);
725 | end = high_resolution_clock::now();
726 | cout << "Linear Search: " << duration_cast(end - start).count() << " Answer: " << ind2 << endl;
727 | }
728 |
729 |
730 | int main()
731 | {
732 | search_playground();
733 | }
734 |
--------------------------------------------------------------------------------