0% found this document useful (0 votes)
43 views12 pages

DSA Day 3

Uploaded by

engg.mohsin1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
43 views12 pages

DSA Day 3

Uploaded by

engg.mohsin1
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

UET LAHORE

NEW CAMPUS

Programming
Session
Phase 1
DSA
Tree
The tree is non-linear, a hierarchical data structure consisting of a collection of nodes, and each
node in the tree contains a value that is a list of references to the node (the “child”).

Application
Traversing: The tree structure becomes a route for the HTML interpreter that can be followed
to traverse throughout the HTML document.
Decision Making: A tree data structure can provide us with an algorithm that can allow a user
to explore movie streaming applications in such a way that they can reach a movie that might be
best recommended for them.

Types
General tree
In this tree, there is no limitation to the number of nodes. It starts with a root node and the parent node's
children make another general sub-tree.
Binary tree
A binary tree node can have up to two child nodes. In a given dendrogram, nodes B, D, and F are children on
the left, and E, C, and G are children on the right.
Balance tree
A tree is said to have a balanced tree data structure if the heights of the left and right subtrees are the same or
differ by up to one.

Balanced Tree Unbalanced Tree

Binary Search Tree


Binary search trees are just like binary trees but values are ordered in a way that each node that descends to the
left side of its parent must have a value less than its parent, and each node that descends to the right side of its
parent must have a value bigger than its parent.
AVL Tree
An AVL tree can be defined as a height-balanced binary search tree.
Difference between the height of the left subtree and the right subtree is considered as the height of the AVL
tree. The value of the balancing factor must be 0, 1 or -1 for each node in an AVL tree.

Red and Black Tree


It's also a self-balancing tree just like an AVL tree, the only difference is in an AVL tree, we do not have an
idea as to how much rotations would be required to balance the tree but in a red black tree a maximum of two
rotations are required to balance the tree. It contains a bit that represents the red or black color of the node to
ensure the balancing of the tree.
Implementation
BST:
#include<iostream>
#include<Windows.h>
using namespace std;
class node {
public:
int data;
node* left;
node* right;
node(int v) : data(v), left(nullptr), right(nullptr) {
}
};

class Tree {
public:
node* root = nullptr;
void simple_insert(int v) {
if (root == nullptr) {
root = new node(v);
}
else {
node* parent = root;
node* child = root;
while (parent != nullptr) {
child = parent;
if (v > parent->data) {
parent = parent->right;
}
else {
parent = parent->left;
}
}
if (v > child->data) {
child->right = new node(v);
}
else {
child->left = new node(v);
}
}
}
void inorder_print(node* root) {
if (root == nullptr) {
return;
}
inorder_print(root->left);
cout << root->data << " -> ";
inorder_print(root->right);
}

node* recursive_insert(node* root, int v) {


if (root == nullptr) {
return new node(v);
}

if (v > root->data) {
root->right = recursive_insert(root->right, v);
}
else {
root->left = recursive_insert(root->left, v);
}
return root;
}

void pre0rder_print(node* root) {


if (root == nullptr) {
return;
}
cout << root->data << " -> ";
inorder_print(root->left);

inorder_print(root->right);
}

void post0rder_print(node* root) {


if (root == nullptr) {
return;
}

inorder_print(root->left);

inorder_print(root->right);
cout << root->data << " -> ";
}

int find_right_min(node* root) {


while (root->left != nullptr) {
root = root->left;
}
return root->data;
}

node* deletion(node* root,int v) {


if (root == nullptr) {
return root;
}
if (v > root->data) {
root->right = deletion(root->right,v);
}
else if (v < root->data) {
root->left = deletion(root->left, v);
}
else {
if (root->left == nullptr ) {
node* temp = root->right;
delete root;
return temp;
}
else if (root->right == nullptr) {
node* temp = root->left;
delete root;
return temp;
}
else {
int right_min = find_right_min(root->right);
root->data = right_min;
root->right = deletion(root->right,right_min);
}

}
return root;
}

};
Height and Diameter of BST
Level Order Traversal

AVL Tree Implementation


Click here.
#include <iostream>
using namespace std;

class Node {
public:
int key;
Node* left;
Node* right;
int height;
};

int max(int a, int b);

// Calculate height
int height(Node* N) {
if (N == NULL)
return 0;
return N->height;
}

int max(int a, int b) {


return (a > b) ? a : b;
}

// New node creation


Node* newNode(int key) {
Node* node = new Node();
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1;
return (node);
}

// Rotate right
Node* rightRotate(Node* y) {
Node* x = y->left;
Node* T2 = x->right;
x->right = y;
y->left = T2;
y->height = max(height(y->left),
height(y->right)) +
1;
x->height = max(height(x->left),
height(x->right)) +
1;
return x;
}

// Rotate left
Node* leftRotate(Node* x) {
Node* y = x->right;
Node* T2 = y->left;
y->left = x;
x->right = T2;
x->height = max(height(x->left),
height(x->right)) +
1;
y->height = max(height(y->left),
height(y->right)) +
1;
return y;
}

// Get the balance factor of each node


int getBalanceFactor(Node* N) {
if (N == NULL)
return 0;
return height(N->left) -
height(N->right);
}

// Insert a node
Node* insertNode(Node* node, int key) {
// Find the correct postion and insert the node
if (node == NULL)
return (newNode(key));
if (key < node->key)
node->left = insertNode(node->left, key);
else if (key > node->key)
node->right = insertNode(node->right, key);
else
return node;

// Update the balance factor of each node and


// balance the tree
node->height = 1 + max(height(node->left),
height(node->right));
int balanceFactor = getBalanceFactor(node);
if (balanceFactor > 1) {
if (key < node->left->key) {
return rightRotate(node);
}
else if (key > node->left->key) {
node->left = leftRotate(node->left);
return rightRotate(node);
}
}
if (balanceFactor < -1) {
if (key > node->right->key) {
return leftRotate(node);
}
else if (key < node->right->key) {
node->right = rightRotate(node->right);
return leftRotate(node);
}
}
return node;
}

// Node with minimum value


Node* nodeWithMimumValue(Node* node) {
Node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}

// Delete a node
Node* deleteNode(Node* root, int key) {
// Find the node and delete it
if (root == NULL)
return root;
if (key < root->key)
root->left = deleteNode(root->left, key);
else if (key > root->key)
root->right = deleteNode(root->right, key);
else {
if ((root->left == NULL) ||
(root->right == NULL)) {
Node* temp = root->left ? root->left : root->right;
if (temp == NULL) {
temp = root;
root = NULL;
}
else
*root = *temp;
free(temp);
}
else {
Node* temp = nodeWithMimumValue(root->right);
root->key = temp->key;
root->right = deleteNode(root->right,
temp->key);
}
}

if (root == NULL)
return root;

// Update the balance factor of each node and


// balance the tree
root->height = 1 + max(height(root->left),
height(root->right));
int balanceFactor = getBalanceFactor(root);
if (balanceFactor > 1) {
if (getBalanceFactor(root->left) >= 0) {
return rightRotate(root);
}
else {
root->left = leftRotate(root->left);
return rightRotate(root);
}
}
if (balanceFactor < -1) {
if (getBalanceFactor(root->right) <= 0) {
return leftRotate(root);
}
else {
root->right = rightRotate(root->right);
return leftRotate(root);
}
}
return root;
}

// Print the tree


void printTree(Node* root, string indent, bool last) {
if (root != nullptr) {
cout << indent;
if (last) {
cout << "R----";
indent += " ";
}
else {
cout << "L----";
indent += "| ";
}
cout << root->key << endl;
printTree(root->left, indent, false);
printTree(root->right, indent, true);
}
}

int main() {
Node* root = NULL;
root = insertNode(root, 33);
root = insertNode(root, 13);
root = insertNode(root, 53);
root = insertNode(root, 9);
root = insertNode(root, 21);
root = insertNode(root, 61);
root = insertNode(root, 8);
root = insertNode(root, 11);
printTree(root, "", true);
root = deleteNode(root, 13);
cout << "After deleting " << endl;
printTree(root, "", true);
}

Heap
A heap is a complete binary tree, and the binary tree is a tree in which the node can have two children.
A complete binary tree is a binary tree in which all the levels except the last level, i.e., leaf node should be
completely filled, and all the nodes should be left-justified.

Min Heap: min-heap can be defined as, for every node i, the value of node i is greater than or equal to its
parent value except the root node. A[Parent(i)] <= A[i]
Max Heap: max heap can be defined as for every node i; the value of node i is less than or equal to its parent
value except the root node. A[Parent(i)] >= A[i]

Implementation:
Click here.

https://www.programiz.com/dsa/binary-search-tree
Algorithms
Merge sort.
void merge(int arr[], int p, int q, int r) {

// Create L ← A[p..q] and M ← A[q+1..r]


int n1 = q - p + 1;
int n2 = r - q;

int* L = new int[n1];


int* M = new int[n2];

for (int i = 0; i < n1; i++)


L[i] = arr[p + i];
for (int j = 0; j < n2; j++)
M[j] = arr[q + 1 + j];

// Maintain current index of sub-arrays and main array


int i, j, k;
i = 0;
j = 0;
k = p;

// Until we reach either end of either L or M, pick larger among


// elements L and M and place them in the correct position at A[p..r]
while (i < n1 && j < n2) {
if (L[i] <= M[j]) {
arr[k] = L[i];
i++;
}
else {
arr[k] = M[j];
j++;
}
k++;
}

// When we run out of elements in either L or M,


// pick up the remaining elements and put in A[p..r]
while (i < n1) {
arr[k] = L[i];
i++;
k++;
}

while (j < n2) {


arr[k] = M[j];
j++;
k++;
}
}
void mergeSort(int arr[], int l, int r) {
if (l < r) {
// m is the point where the array is divided into two subarrays
int m = l + (r - l) / 2;

mergeSort(arr, l, m);
mergeSort(arr, m + 1, r);

// Merge the sorted subarrays


merge(arr, l, m, r);
}
}

Quick sort.
int partition(int array[], int low, int high) {

// select the rightmost element as pivot


int pivot = array[high];

// pointer for greater element


int i = (low - 1);

// traverse each element of the array


// compare them with the pivot
for (int j = low; j < high; j++) {
if (array[j] <= pivot) {

// if element smaller than pivot is found


// swap it with the greater element pointed by i
i++;

// swap element at i with element at j


swap(array[i], array[j]);
}
}

// swap pivot with the greater element at i


swap(array[i + 1], array[high]);

// return the partition point


return (i + 1);
}

void quickSort(int array[], int low, int high) {


if (low < high) {

// find the pivot element such that


// elements smaller than pivot are on left of pivot
// elements greater than pivot are on righ of pivot
int pi = partition(array, low, high);

// recursive call on the left of pivot


quickSort(array, low, pi - 1);

// recursive call on the right of pivot


quickSort(array, pi + 1, high);
}
}
Swap is a built-in function in C++.
Heap sort.
Insert each array element into the min heap. Then, call the Min heap delete function n times to obtain a sorted
array.
Time complexity
Algorithms Best Case Worst Case
Merge sort O(nlogn) O(nlogn)
Quick sort O(nlogn) O(n2)
Heap sort O(nlogn) O(nlogn)

You might also like