Skip to content

Commit

Permalink
Merge pull request #1835 from aditiverma-21/main
Browse files Browse the repository at this point in the history
Conversion of Linked List to Balanced Binary Search Tree
  • Loading branch information
pankaj-bind authored Nov 10, 2024
2 parents 472c2b9 + 2066241 commit 2fac1e8
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 0 deletions.
115 changes: 115 additions & 0 deletions Linked_list/Linkedlist_to_BST/program.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include <stdio.h>
#include <stdlib.h>

// Define the structure for the linked list node
struct ListNode {
int val;
struct ListNode *next;
};

// Define the structure for the tree node (BST)
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
};

// Function to create a new list node
struct ListNode* createListNode(int val) {
struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
newNode->val = val;
newNode->next = NULL;
return newNode;
}

// Function to create a new tree node
struct TreeNode* createTreeNode(int val) {
struct TreeNode* newNode = (struct TreeNode*)malloc(sizeof(struct TreeNode));
newNode->val = val;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}

// Function to find the size of the linked list
int getListSize(struct ListNode* head) {
int size = 0;
while (head) {
size++;
head = head->next;
}
return size;
}

// Function to convert the linked list to a balanced BST
struct TreeNode* sortedListToBSTHelper(struct ListNode** headRef, int size) {
if (size <= 0) {
return NULL;
}

// Recursively build the left subtree
struct TreeNode* left = sortedListToBSTHelper(headRef, size / 2);

// The middle node will be the root of the current subtree
struct TreeNode* root = createTreeNode((*headRef)->val);
root->left = left;

// Move the head pointer to the next node in the list
*headRef = (*headRef)->next;

// Recursively build the right subtree
root->right = sortedListToBSTHelper(headRef, size - size / 2 - 1);

return root;
}

// Function to convert the sorted linked list to a balanced BST
struct TreeNode* sortedListToBST(struct ListNode* head) {
int size = getListSize(head);
return sortedListToBSTHelper(&head, size);
}

// In-order traversal of the binary search tree (for testing)
void inorderTraversal(struct TreeNode* root) {
if (root) {
inorderTraversal(root->left);
printf("%d ", root->val);
inorderTraversal(root->right);
}
}

// Helper function to create a sorted linked list
struct ListNode* createLinkedList(int arr[], int size) {
struct ListNode* head = NULL;
struct ListNode* temp = NULL;
for (int i = 0; i < size; i++) {
struct ListNode* newNode = createListNode(arr[i]);
if (head == NULL) {
head = newNode;
} else {
temp->next = newNode;
}
temp = newNode;
}
return head;
}

int main() {
// Example sorted linked list: [-10, -3, 0, 5, 9]
int arr[] = {-10, -3, 0, 5, 9};
int size = sizeof(arr) / sizeof(arr[0]);

// Create the linked list from the array
struct ListNode* head = createLinkedList(arr, size);

// Convert the sorted linked list to a balanced BST
struct TreeNode* root = sortedListToBST(head);

// Print the in-order traversal of the tree
printf("In-order traversal of the balanced BST: ");
inorderTraversal(root);
printf("\n");

return 0;
}

42 changes: 42 additions & 0 deletions Linked_list/Linkedlist_to_BST/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Conversion of Linked List to Balanced Binary Tree

## Overview
To convert a sorted linked list into a balanced binary search tree (BST), we need to carefully choose the middle element of the linked list to maintain the balance of the tree. A balanced BST ensures that the left and right subtrees of every node have a minimal height difference, which optimizes search, insert, and delete operations.

## Steps:
1. Calculate the size of the linked list: This helps in determining the middle element for the root.
2. Recursively build the BST by finding the middle element of the list and using it as the root.
3. Move the linked list pointer while constructing the tree to ensure we are processing the nodes in sequence.

## Explanation:
1. ListNode and TreeNode Structures:

- ListNode represents a node in the linked list with an integer value and a pointer to the next node.
- TreeNode represents a node in the binary search tree (BST), which contains a value, and pointers to its left and right children.
2. Helper Functions:

- createListNode: Creates a new linked list node.
- createTreeNode: Creates a new tree node.
- getListSize: Finds the size of the linked list.
- sortedListToBSTHelper: Recursively builds the balanced BST. It takes the current head of the list (passed as a reference) and the size of the current list segment.
- sortedListToBST: Initializes the process of converting the linked list into a BST by calling the helper function with the list's size.
3. In-order Traversal:

- The inorderTraversal function prints the tree nodes in sorted order (since it’s a binary search tree), which can help verify the correctness of the conversion.
- Helper Function to Create Linked List:

- The createLinkedList function converts an array into a sorted linked list. This is helpful for testing the solution.
4. Main Function:

- We create a sorted linked list [-10, -3, 0, 5, 9].
- We convert this linked list into a balanced BST using the sortedListToBST function.
- The result is printed using in-order traversal, which should print the sorted elements of the BST in the same order.

### Time Complexity:
- Finding the size of the linked list: **O(n)**, where n is the number of nodes in the list.
- Recursive BST construction: O(n), since each node of the linked list is processed exactly once.
Thus, the overall time complexity is O(n), where n is the number of nodes in the linked list.

### Space Complexity:
- Recursive stack space: **O(log n)**,
- where n is the number of nodes in the linked list (since we are constructing a balanced tree).
Empty file.
27 changes: 27 additions & 0 deletions Linked_list/unroll_linkedList/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# **UNROLLED LINKED LIST**
An **Unrolled Linked List** is a variation of a linked list where each node contains an array of elements rather than a single element. This setup reduces the number of nodes and can improve cache performance, especially for applications with high memory allocation or traversal requirements.

Here’s how an **Unrolled Linked List** is typically structured:
- Each node has an array of elements.
- Each node maintains the count of elements it currently holds.
- When an array (node) is full, it splits into two nodes, maintaining balance.

This structure is especially useful in memory-intensive applications or those that frequently iterate over list elements, like graphics rendering.

### Explanation of Code:

1. **Node Structure (`UnrolledNode`)**: Each node has a fixed-size array (`elements`) to hold multiple elements and a `count` to keep track of the number of elements in that node.

2. **Insertion Logic**:
- Traverse to the last node in the list with available space.
- If the node is full, create a new node and split the current node's elements between the old and new nodes.
- Insert the new element in the appropriate node based on its value relative to the split elements.

3. **Printing**:
- Each node's elements are printed to verify the structure and content of the list.

### Notes:
- **NODE_CAPACITY**: This is set to 4 for simplicity, but in practice, it can be larger (often 16 or 32).
- **Performance**: Unrolled linked lists have better cache performance and lower memory overhead than standard linked lists due to fewer nodes.

Unrolled linked lists are helpful in applications that benefit from reduced node traversal times, like text editors or data structures that require frequent insertions, deletions, and searches.

0 comments on commit 2fac1e8

Please sign in to comment.