-
Notifications
You must be signed in to change notification settings - Fork 303
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1835 from aditiverma-21/main
Conversion of Linked List to Balanced Binary Search Tree
- Loading branch information
Showing
4 changed files
with
184 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |