Skip to content

Commit

Permalink
Merge pull request #1 from AlgoGenesis/main
Browse files Browse the repository at this point in the history
union of two 1D Arrays AlgoGenesis#1684
  • Loading branch information
Aachallll authored Nov 11, 2024
2 parents 0cb932e + f4cdf26 commit fe3fb6d
Show file tree
Hide file tree
Showing 50 changed files with 3,030 additions and 13 deletions.
12 changes: 0 additions & 12 deletions .github/ISSUE_TEMPLATE/new_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name: "Add New Algorithm"
about: Propose a new algorithm to be added to the repository
title: "[NEW ALGORITHM] "
labels: new algorithm, gssoc-ext, hacktoberfest, level1
assignees: ''
---

Expand All @@ -21,14 +20,3 @@ assignees: ''

### About:
Propose a new algorithm to be added to the repository

---

### Labels:
```new algorithm, gssoc-ext, hacktoberfest, level1```

---

### Assignees:
- [ ] Contributor in GSSoC-ext
- [ ] Want to work on it
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/update_algorithm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
name: Update Algorithm
about: Suggest changes to an existing algorithm
title: "[UPDATE ALGORITHM] "
labels: algorithm update, gssoc-ext, hacktoberfest, level1
assignees: ''
---

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Non-Recursive Binary Tree Traversal

This section describes the implementation of functions in C that performs non-recursive traversal of a binary tree. Here offers pre-order, in-order, and post-order traversals.

## Problem Statement
Given a binary tree, implement pre-order, in-order, and post-order traversals of the tree in a non-recursive manner.

## Solution
To perform non-recursive traversal of a binary tree, we utilize a stack data structure. The `StackNode` struct is essential as it allows us to keep track of the nodes during traversal. Each `StackNode` contains a pointer to a `Node` of the binary tree and a pointer to the next `StackNode`, mimicking the Last-In-First-Out (LIFO) behavior of a stack.

### 1. pre-order Traversal
In pre-order traversal, we visit the root node first, then recursively perform pre-order traversal on the left subtree, and finally on the right subtree.

**Implementation Details:**
- Initialize an empty stack and push the root node onto the stack.
- Pop a node from the stack, visit it, and push its right child followed by its left child onto the stack.
- Repeat the process until the stack is empty.

### 2. in-order Traversal
In in-order traversal, we recursively perform in-order traversal on the left subtree, visit the root node, and then recursively perform in-order traversal on the right subtree.

**Implementation Details:**
- Initialize an empty stack and set the current node to the root.
- Push all left children of the current node onto the stack until a leaf node is reached.
- Pop a node from the stack, visit it, set the current node to its right child, and repeat the process.
- If the current node is NULL and the stack is empty, the traversal is complete.

### 3. post-order Traversal
In post-order traversal, we recursively perform post-order traversal on the left subtree, then on the right subtree, and finally visit the root node.

**Implementation Details:**
- Initialize two stacks, `stack1` and `stack2`.
- Push the root node onto `stack1`.
- Pop a node from `stack1`, push it onto `stack2`, and then push its left child followed by its right child onto `stack1`.
- Repeat the process until `stack1` is empty.
- Pop nodes from `stack2` and visit them, which will be in post-order since the last nodes to be popped from `stack1` are the leftmost nodes.
144 changes: 144 additions & 0 deletions Binary Tree Algorithms/Non-Recursion Traversal Algorithms/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>


typedef struct Node {
int data;
struct Node *left;
struct Node *right;
} Node;


typedef struct StackNode {
Node *treeNode;
// Pointer to the next stack node
struct StackNode *next;
} StackNode;

// Function to create a new node
Node* newNode(int data) {
Node *node = (Node *)malloc(sizeof(Node));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}

// Function to create a new stack node
StackNode* newStackNode(Node *treeNode) {
StackNode *stackNode = (StackNode *)malloc(sizeof(StackNode));
stackNode->treeNode = treeNode;
stackNode->next = NULL;
return stackNode;
}

// Function to check if the stack is empty
int isStackEmpty(StackNode *top) {
return top == NULL;
}

// Function to push a node onto the stack
void push(StackNode **top, Node *treeNode) {
StackNode *newStackNode = (StackNode *)malloc(sizeof(StackNode));
newStackNode->treeNode = treeNode;
newStackNode->next = *top;
*top = newStackNode;
}

// Function to pop a node from the stack
Node* pop(StackNode **top) {
if (isStackEmpty(*top)) {
return NULL;
}
StackNode *temp = *top;
Node *treeNode = temp->treeNode;
*top = temp->next;
free(temp);
return treeNode;
}

// Function to get the top node of the stack
Node* top(StackNode *top) {
if (isStackEmpty(top)) {
return NULL;
}
return top->treeNode;
}

// Function to perform preorder traversal of the tree
void preorderTraversal(Node *root) {
if (root == NULL) return;
StackNode *stack = NULL;
// Push the root node onto the stack
push(&stack, root);
while (!isStackEmpty(stack)) {
Node *current = pop(&stack);
// Print the data
printf("%d ", current->data);
if (current->right) push(&stack, current->right);
if (current->left) push(&stack, current->left);
}
}

// Function to perform inorder traversal of the tree
void inorderTraversal(Node *root) {
if (root == NULL) return;
StackNode *stack = NULL;
Node *current = root;
while (current != NULL || !isStackEmpty(stack)) {
while (current != NULL) {
// Push nodes onto the stack
push(&stack, current);
// Move to the left child
current = current->left;
}
current = pop(&stack);
printf("%d ", current->data);
// Move to the right child
current = current->right;
}
}

// Function to perform postorder traversal of the tree
void postorderTraversal(Node *root) {
if (root == NULL) return;
// Initialize stack1
StackNode *stack1 = NULL;
// Initialize stack2
StackNode *stack2 = NULL;
// Push the root node onto stack1
push(&stack1, root);
while (!isStackEmpty(stack1)) {
Node *current = pop(&stack1);
// Push the node onto stack2
push(&stack2, current);
// Push left child if it exists
if (current->left) push(&stack1, current->left);
// Push right child if it exists
if (current->right) push(&stack1, current->right);
}
while (!isStackEmpty(stack2)) {
// Pop a node from stack2
Node *current = pop(&stack2);
printf("%d ", current->data);
}
}

// Main function to demonstrate tree traversals
int main() {
Node* root = newNode(10);
root->left = newNode(5);
root->right = newNode(20);
root->left->left = newNode(3);
root->left->right = newNode(8);
printf("Preorder traversal: ");
preorderTraversal(root);
printf("\n");
printf("Inorder traversal: ");
inorderTraversal(root);
printf("\n");
printf("Postorder traversal: ");
postorderTraversal(root);
printf("\n");
return 0;
}
34 changes: 34 additions & 0 deletions Bitwise Algorithms/Euclid's Algorithm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <stdio.h>

int BitwiseGCD(int a, int b)
{
// Base cases
if (b == 0 || a == b) return a;
if (a == 0) return b;

// If both a and b are even
// divide both a and b by 2. And multiply the result with 2
if ( (a & 1) == 0 && (b & 1) == 0 )
return gcd(a>>1, b>>1) << 1;

// If a is even and b is odd, divide a by 2
if ( (a & 1) == 0 && (b & 1) != 0 )
return gcd(a>>1, b);

// If a is odd and b is even, divide b by 2
if ( (a & 1) != 0 && (b & 1) == 0 )
return gcd(a, b>>1);

// If both are odd, then apply normal subtraction algorithm.
// Note that odd-odd case always converts odd-even case after one recursion
return (a > b)? gcd(a-b, b): gcd(a, b-a);
}

int main() {
int m, n;
printf("Enter two nonnegative integers: ");
scanf("%d %d", &m, &n);
int gcd = BitwiseGCD(m, n);
printf("Greatest common divisor (GCD) of %d and %d is: %d\n", m, n, gcd);
return 0;
}
90 changes: 90 additions & 0 deletions Bitwise Algorithms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Euclid’s Algorithm when % and / operations are costly



**Euclid’s algorithm** is used to find **Greatest Common Divisor (GCD)** of two numbers. There are mainly **two** versions of algorithm.
- Using subtraction
- Using modulo operator


### Version 1 (Using subtraction)
```plaintext
// Recursive function to return gcd of a and b
int gcd(int a, int b)
{
if (a == b) return a;
return (a > b)? gcd(a-b, b): gcd(a, b-a);
}
```
**Time Complexity** : O(max(a, b))
**Space Complexity** : O(1)



## Version 2 (Using modulo operator)

```plaintext
// Function to return gcd of a and b
int gcd(int a, int b)
{
if (a == 0) return b;
return gcd(b%a, a);
}
```

**Time Complexity** : O(log(max(a, b)))
**Space Complexity** : O(1)


Version 1 can take linear time to find the GCD.
Consider the situation when one of the given numbers is much bigger than the other:
Version 2 is obviously more efficient as there are less recursive calls and takes logarithmic time.

**Consider a situation where modulo operator is not allowed, can we optimize version 1 to work faster?**

Below are some important observations. The idea is to use bitwise operators.
We can find x/2 using x>>1. We can check whether x is odd or even using x&1.
- gcd(a, b) = 2*gcd(a/2, b/2) if both a and b are even.
- gcd(a, b) = gcd(a/2, b) if a is even and b is odd.
- gcd(a, b) = gcd(a, b/2) if a is odd and b is even.


## Bitwise Algorithms:

### Implementation using Bitwise Operators:

```plaintext
int gcd(int a, int b)
{
// Base cases
if (b == 0 || a == b) return a;
if (a == 0) return b;
// If both a and b are even, divide both a
// and b by 2. And multiply the result with 2
if ( (a & 1) == 0 && (b & 1) == 0 )
return gcd(a>>1, b>>1) << 1;
// If a is even and b is odd, divide a by 2
if ( (a & 1) == 0 && (b & 1) != 0 )
return gcd(a>>1, b);
// If a is odd and b is even, divide b by 2
if ( (a & 1) != 0 && (b & 1) == 0 )
return gcd(a, b>>1);
// If both are odd, then apply normal subtraction
// algorithm. Note that odd-odd case always
// converts odd-even case after one recursion
return (a > b)? gcd(a-b, b): gcd(a, b-a);
}
```

**Time Complexity** : O(log(max(a, b)))
**Space Complexity** : O(1)

The Time and Space Complexity remains same as using the modulo operators.
Loading

0 comments on commit fe3fb6d

Please sign in to comment.