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 StructureOperationBestAverageWorst
Linked ListAccessO(n)O(n)O(n)
SearchO(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)
StackPushO(1)O(1)O(1)
PopO(1)O(1)O(1)
PeekO(1)O(1)O(1)
QueueEnqueueO(1)O(1)O(1)
DequeueO(1)O(1)O(1)
PeekO(1)O(1)O(1)
Binary Search Tree (BST)SearchO(log n)O(log n)O(n)
InsertO(log n)O(log n)O(n)
DeleteO(log n)O(log n)O(n)
AVL TreeSearchO(log n)O(log n)O(log n)
InsertO(log n)O(log n)O(log n)
DeleteO(log n)O(log n)O(log n)
Heap (Binary Heap)InsertO(1)O(log n)O(log n)
Extract Min / MaxO(log n)O(log n)O(log n)
PeekO(1)O(1)O(1)
HeapifyO(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;
        }
    }
}