Data Structures and Algorithms Code Snippets
Data Structures and Algorithms Implementations
Merge Sort Implementation
The mergeSort method recursively divides the array and then merges the sorted halves.
public static void mergeSort(int[] array) {
int length = array.length;
if (length <= 1)
return;
int middle = length / 2;
int[] leftArray = new int[middle];
int[] rightArray = new int[length - middle];
int j = 0;
for (int i = 0; i < length; i++) {
if (i < middle)
leftArray[i] = array[i];
else
rightArray[j++] = array[i];
}
mergeSort(leftArray);
mergeSort(rightArray);
merge(leftArray, rightArray, array);
}
The merge method combines two sorted arrays into one.
public static void merge(int[] leftArray, int[] rightArray, int[] array) {
int leftSize = leftArray.length;
int rightSize = rightArray.length;
int i = 0, l = 0, r = 0;
while (l < leftSize && r < rightSize) {
if (leftArray[l] < rightArray[r])
array[i++] = leftArray[l++];
else
array[i++] = rightArray[r++];
}
while (l < leftSize)
array[i++] = leftArray[l++];
while (r < rightSize)
array[i++] = rightArray[r++];
}
Quick Sort Implementation
The quickSort method uses the partition scheme to sort the array.
public static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pivotIndex = partition(arr, low, high);
quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}
private static int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] <= pivot) {
i++;
swap(arr, i, j);
}
}
swap(arr, i + 1, high);
return i + 1;
}
Data Structure Time Complexities
A comparison of common data structure operations:
| Data Structure | Operation | Best | Average | Worst |
|---|---|---|---|---|
| Linked List | Access | O(n) | O(n) | O(n) |
| Search | O(n) | O(n) | O(n) | |
| Insert (at head) | O(1) | O(1) | O(1) | |
| Insert (at tail, no tail pointer) | O(n) | O(n) | O(n) | |
| Delete (given node) | O(1) | O(1) | O(1) | |
| Delete (by value) | O(n) | O(n) | O(n) | |
| Stack | Push | O(1) | O(1) | O(1) |
| Pop | O(1) | O(1) | O(1) | |
| Peek | O(1) | O(1) | O(1) | |
| Queue | Enqueue | O(1) | O(1) | O(1) |
| Dequeue | O(1) | O(1) | O(1) | |
| Peek | O(1) | O(1) | O(1) | |
| Binary Search Tree (BST) | Search | O(log n) | O(log n) | O(n) |
| Insert | O(log n) | O(log n) | O(n) | |
| Delete | O(log n) | O(log n) | O(n) | |
| AVL Tree | Search | O(log n) | O(log n) | O(log n) |
| Insert | O(log n) | O(log n) | O(log n) | |
| Delete | O(log n) | O(log n) | O(log n) | |
| Heap (Binary Heap) | Insert | O(1) | O(log n) | O(log n) |
| Extract Min / Max | O(log n) | O(log n) | O(log n) | |
| Peek | O(1) | O(1) | O(1) | |
| Heapify | O(n) | O(n) | O(n) |
AVL Tree Structure
The structure for an AVL Tree node, including height tracking.
class AVLTree {
class Node {
int key, height;
Node left, right;
Node(int key) {
this.key = key;
height = 1;
}
}
private Node root;
private int height(Node node) {
if (node == null)
return 0;
return node.height;
}
private int getBalance(Node node) {
if (node == null)
return 0;
return height(node.left) - height(node.right);
}
private Node rightRotate(Node y) {
Node x = y.left;
Node T2 = x.right;
// Perform rotation
x.right = y;
y.left = T2;
// Update heights
y.height = Math.max(height(y.left), height(y.right)) + 1;
x.height = Math.max(height(x.left), height(x.right)) + 1;
return x;
}
private Node leftRotate(Node x) {
Node y = x.right;
Node T2 = y.left;
// Perform rotation
y.left = x;
x.right = T2;
// Update heights
x.height = Math.max(height(x.left), height(x.right)) + 1;
y.height = Math.max(height(y.left), height(y.right)) + 1;
return y;
}
public Node insert(Node node, int key) {
if (node == null)
return new Node(key);
if (key < node.key)
node.left = insert(node.left, key);
else if (key > node.key)
node.right = insert(node.right, key);
else
return node; // Duplicates not allowed
node.height = 1 + Math.max(height(node.left), height(node.right));
int balance = getBalance(node);
// LL Case
if (balance > 1 && key < node.left.key)
return rightRotate(node);
// RR Case
if (balance < -1 && key > node.right.key)
return leftRotate(node);
// LR Case
if (balance > 1 && key > node.left.key) {
node.left = leftRotate(node.left);
return rightRotate(node);
}
// RL Case
if (balance < -1 && key < node.right.key) {
node.right = rightRotate(node.right);
return leftRotate(node);
}
return node;
}
public Node delete(Node root, int key) {
if (root == null)
return root;
if (key < root.key)
root.left = delete(root.left, key);
else if (key > root.key)
root.right = delete(root.right, key);
else {
// Node with only one child or no child
if (root.left == null || root.right == null) {
Node temp;
if (root.left != null)
temp = root.left;
else
temp = root.right;
if (temp == null) {
root = null;
} else
root = temp;
} else {
// Node with two children: Get the inorder successor (smallest in the right subtree)
Node temp = minValueNode(root.right);
root.key = temp.key;
root.right = delete(root.right, temp.key);
}
}
if (root == null)
return root;
root.height = Math.max(height(root.left), height(root.right)) + 1;
int balance = getBalance(root);
// Left Left Case
if (balance > 1 && getBalance(root.left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root.left) < 0) {
root.left = leftRotate(root.left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root.right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root.right) > 0) {
root.right = rightRotate(root.right);
return leftRotate(root);
}
return root;
}
// Helper method for deletion (assumed to be defined elsewhere or needs definition)
private Node minValueNode(Node node) {
Node current = node;
while (current.left != null)
current = current.left;
return current;
}
}
MinHeap Class
Implementation of a basic Min Heap structure.
class MinHeap {
private int[] heap;
private int size;
public MinHeap(int capacity) {
heap = new int[capacity];
size = 0;
}
public void insert(int value) {
heap[size] = value;
bubbleUp(size);
size++;
}
public int extractMin() {
int min = heap[0];
heap[0] = heap[size - 1];
size--;
bubbleDown(0);
return min;
}
private int parent(int i) { return (i - 1) / 2; }
private int left(int i) { return (2 * i) + 1; }
private int right(int i) { return (2 * i) + 2; }
private void swap(int i, int j) {
int temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
private void bubbleUp(int i) {
while (i > 0 && heap[parent(i)] > heap[i]) {
swap(i, parent(i));
i = parent(i);
}
}
private void bubbleDown(int i) {
while (left(i) < size) {
int smallest = left(i);
if (right(i) < size && heap[right(i)] < heap[smallest])
smallest = right(i);
if (heap[i] <= heap[smallest])
break;
swap(i, smallest);
i = smallest;
}
}
}
