Dsa Unit 2 (Ai)
Dsa Unit 2 (Ai)
class TreeNode {
public:
int data;
vector<TreeNode*> children; // For general trees
TreeNode(int val) {
data = val;
}
};
A Binary Tree is a tree where each node has at most two children.
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = right = nullptr;
}
};
int main() {
Node* root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
return 0;
}
Types of Trees
1. Binary Search Tree (BST) - A binary tree where left child < root < right child.
2. Balanced Trees (AVL, Red-Black Tree) - Ensures logarithmic time complexity.
3. Heap (Min-Heap, Max-Heap) - A complete binary tree used for priority queues.
4. Trie (Prefix Tree) - Used for storing and searching strings efficiently.
5. Segment Tree & Fenwick Tree - Used for range queries.
Let me know if you need more explanations on any specific type of tree! 🚀
Binary Trees in C++
A Binary Tree is a hierarchical data structure in which each node has at most two
children:
● Left Child
● Right Child
Each node stores a value and pointers to its left and right children.
Node Structure
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int val) {
data = val;
left = right = nullptr;
}
};
Binary Tree Traversal
Binary tree traversal means visiting every node of the tree in a specific order.
#include <queue>
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* temp = q.front();
q.pop();
cout << temp->data << " ";
if (temp->left) q.push(temp->left);
if (temp->right) q.push(temp->right);
}
}
return root;
}
return 0;
}
Conclusion
● Binary trees efficiently store hierarchical data.
● Traversals (DFS & BFS) help in tree processing.
● Manipulation operations like insertion, deletion, and searching are crucial for
tree-based applications.
Example: Expression 3 + 5 * 2
+
/\
3 *
/\
5 2
● The multiplication (*) is performed before the addition (+) due to operator
precedence.
C++ Implementation
#include <iostream>
#include <stack>
using namespace std;
Node(char val) {
data = val;
left = right = nullptr;
}
};
return st.top();
}
int main() {
string postfix = "35*2+"; // Represents: (3 + (5 * 2))
Node* root = constructTree(postfix);
return 0;
}
Output
Inorder Expression: (3+(5*2))
Postorder Traversal: 3 5 2 * +
1. The left subtree of a node contains only nodes with values less than the node.
2. The right subtree of a node contains only nodes with values greater than the
node.
3. The left and right subtrees must also be binary search trees.
Example BST
10
/ \
5 15
/\ / \
2 7 12 18
Operations on a BST
1. Insertion in a BST
Node* insertBST(Node* root, int val) {
if (root == nullptr) return new Node(val);
return root;
}
2. Searching in a BST
bool searchBST(Node* root, int key) {
if (root == nullptr) return false;
if (root->data == key) return true;
if (key < root->data) return searchBST(root->left, key);
return searchBST(root->right, key);
}
3. Deletion in a BST
Advantages of BST
1. Efficient Searching - O(log N) time complexity for balanced BSTs.
2. Sorted Order - Inorder traversal of BST gives elements in ascending order.
3. Dynamic Set Operations - Supports insert, delete, and search efficiently.
Applications of BST
1. Database Indexing
○ BSTs (like B-Trees) are used in database indexing.
2. Auto-suggestions in Search Engines
○ BSTs help in prefix-based search.
3. Symbol Table in Compilers
○ Used to store variable/function names efficiently.
4. Memory Management
○ Used in malloc() / free() memory allocation algorithms.
5. File System Organization
○ File system hierarchies follow BST-like structures.
Conclusion
● Expression Trees are used in expression evaluation and compiler syntax trees.
● BSTs are efficient for searching, insertion, and deletion.
● BSTs have applications in databases, memory management, and search
engines.
Would you like me to cover Balanced BSTs (AVL, Red-Black Trees) as well? 🚀
Heaps and Priority Queues in C++
A Heap is a complete binary tree where the values are arranged based on a specific
order property. It is mainly used for priority queues and efficient retrieval of the
minimum or maximum element.
Types of Heaps
1. Min-Heap
○ The smallest element is at the root.
○ Every parent node is smaller than or equal to its children.
Example:
10
/ \
20 15
/ \
○
2. 30 40
3. Max-Heap
○ The largest element is at the root.
○ Every parent node is greater than or equal to its children.
Example:
50
/ \
30 40
/ \
○
4. 20 10
Heap Operations
1. Insertion (O(log N))
if (smallest != index) {
swap(heap[index], heap[smallest]);
heapifyDown(smallest);
}
}
public:
void insert(int val) {
heap.push_back(val);
heapifyUp(heap.size() - 1);
}
int extractMin() {
if (heap.empty()) return -1;
int minVal = heap[0];
heap[0] = heap.back();
heap.pop_back();
heapifyDown(0);
return minVal;
}
void display() {
for (int val : heap) cout << val << " ";
cout << endl;
}
};
int main() {
MinHeap h;
h.insert(10);
h.insert(20);
h.insert(5);
h.insert(30);
h.insert(15);
return 0;
}
Output
Min-Heap: 5 15 10 30 20
Extracted Min: 5
After Extraction: 10 15 20 30
class MaxHeap {
vector<int> heap;
if (largest != index) {
swap(heap[index], heap[largest]);
heapifyDown(largest);
}
}
public:
void insert(int val) {
heap.push_back(val);
heapifyUp(heap.size() - 1);
}
int extractMax() {
if (heap.empty()) return -1;
int maxVal = heap[0];
heap[0] = heap.back();
heap.pop_back();
heapifyDown(0);
return maxVal;
}
};
Priority Queue in C++
A Priority Queue is an abstract data structure similar to a queue, but elements are
processed based on priority rather than order of arrival.
int main() {
priority_queue<int> pq; // Max-Heap by default
pq.push(10);
pq.push(20);
pq.push(5);
pq.push(30);
Output
Max Priority Queue: 30 20 10 5
int main() {
priority_queue<int, vector<int>, greater<int>> pq; // Min-Heap
pq.push(10);
pq.push(20);
pq.push(5);
pq.push(30);
Output
Min Priority Queue: 5 10 20 30
Conclusion
● Heaps are specialized complete binary trees for efficient min/max retrieval.
● Priority Queues use heaps for priority-based processing.
● STL priority_queue provides an easy-to-use heap implementation.