Skip to content
IRC-Coding IRC-Coding
Data Structures Stack Queue Heap Array Tree Graph Algorithms Complexity Big O Notation Java

Data Structures Fundamentals: Stack, Queue, Heap, Array, Tree, Graph

Learn data structures fundamentals: stack, queue, heap, array, tree, graph. Algorithms and complexity analysis with Java examples.

S

schutzgeist

2 min read

Data Structures Basics: Stack, Queue, Heap, Array, Tree, Graph

Data structures are fundamental concepts in computer science that organize and manage data. Choosing the right data structure significantly influences the efficiency of algorithms.

What are Data Structures?

Data structures define how data is stored, organized, and accessed. They determine the complexity of operations such as insertion, deletion, and searching.

Classification of Data Structures

  1. Linear Structures: Array, Stack, Queue, Linked List
  2. Hierarchical Structures: Tree, Heap
  3. Network Structures: Graph
  4. Hash-based Structures: Hash Table, Hash Set

Array (Field)

Basics

Arrays are the simplest data structure with direct index access.

public class ArrayDemo {
    public static void main(String[] args) {
        // Static Array
        int[] numbers = new int[5];
        numbers[0] = 10;
        numbers[1] = 20;
        numbers[2] = 30;
        numbers[3] = 40;
        numbers[4] = 50;
        
        // Dynamic Array (ArrayList)
        List<Integer> dynamicArray = new ArrayList<>();
        dynamicArray.add(10);
        dynamicArray.add(20);
        dynamicArray.add(30);
        
        // Array Operations
        System.out.println("Element at index 2: " + numbers[2]); // O(1)
        
        // Linear Search
        int index = linearSearch(numbers, 30); // O(n)
        System.out.println("30 found at index: " + index);
        
        // Sorting with Binary Search
        Arrays.sort(numbers); // O(n log n)
        int sortedIndex = Arrays.binarySearch(numbers, 30); // O(log n)
        System.out.println("30 (sorted) at index: " + sortedIndex);
    }
    
    // Linear search in array
    public static int linearSearch(int[] arr, int target) {
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == target) {
                return i;
            }
        }
        return -1; // Not found
    }
}

Dynamic Array Implementation

public class DynamicArray<T> {
    private Object[] data;
    private int size;
    private int capacity;
    
    public DynamicArray() {
        this.capacity = 10;
        this.data = new Object[capacity];
        this.size = 0;
    }
    
    public void add(T element) {
        if (size >= capacity) {
            resize();
        }
        data[size++] = element;
    }
    
    @SuppressWarnings("unchecked")
    public T get(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        return (T) data[index];
    }
    
    public void set(int index, T element) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        data[index] = element;
    }
    
    public void remove(int index) {
        if (index < 0 || index >= size) {
            throw new IndexOutOfBoundsException();
        }
        
        // Shift elements to the left
        for (int i = index; i < size - 1; i++) {
            data[i] = data[i + 1];
        }
        size--;
    }
    
    private void resize() {
        capacity *= 2;
        data = Arrays.copyOf(data, capacity);
    }
    
    public int size() { return size; }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("[");
        for (int i = 0; i < size; i++) {
            sb.append(data[i]);
            if (i < size - 1) sb.append(", ");
        }
        sb.append("]");
        return sb.toString();
    }
}

Stack (Stack)

LIFO Principle

Stacks follow the Last-In-First-Out (LIFO) principle.

public class StackDemo {
    public static void main(String[] args) {
        // Java Stack
        Stack<Integer> stack = new Stack<>();
        
        // Push Operations
        stack.push(10);
        stack.push(20);
        stack.push(30);
        
        System.out.println("Stack: " + stack);
        System.out.println("Top Element: " + stack.peek()); // 30
        
        // Pop Operation
        int popped = stack.pop(); // Removes 30
        System.out.println("Popped: " + popped);
        System.out.println("Stack after pop: " + stack);
        
        // Practical Application: Parenthesis Checking
        String expression = "{[()]}";
        boolean isBalanced = isBalancedParentheses(expression);
        System.out.println("Expression balanced: " + isBalanced);
    }
    
    // Parenthesis checking with stack
    public static boolean isBalancedParentheses(String expression) {
        Stack<Character> stack = new Stack<>();
        
        for (char c : expression.toCharArray()) {
            switch (c) {
                case '(':
                case '[':
                case '{':
                    stack.push(c);
                    break;
                case ')':
                    if (stack.isEmpty() || stack.pop() != '(') return false;
                    break;
                case ']':
                    if (stack.isEmpty() || stack.pop() != '[') return false;
                    break;
                case '}':
                    if (stack.isEmpty() || stack.pop() != '{') return false;
                    break;
            }
        }
        
        return stack.isEmpty();
    }
}

Stack Implementation

public class ArrayStack<T> {
    private Object[] data;
    private int top;
    private int capacity;
    
    public ArrayStack() {
        this.capacity = 10;
        this.data = new Object[capacity];
        this.top = -1;
    }
    
    public void push(T element) {
        if (isFull()) {
            resize();
        }
        data[++top] = element;
    }
    
    @SuppressWarnings("unchecked")
    public T pop() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return (T) data[top--];
    }
    
    @SuppressWarnings("unchecked")
    public T peek() {
        if (isEmpty()) {
            throw new EmptyStackException();
        }
        return (T) data[top];
    }
    
    public boolean isEmpty() {
        return top == -1;
    }
    
    public boolean isFull() {
        return top == capacity - 1;
    }
    
    private void resize() {
        capacity *= 2;
        data = Arrays.copyOf(data, capacity);
    }
    
    public int size() {
        return top + 1;
    }
}

Queue (Queue)

FIFO Principle

Queues follow the First-In-First-Out (FIFO) principle.

public class QueueDemo {
    public static void main(String[] args) {
        // Java Queue with LinkedList
        Queue<Integer> queue = new LinkedList<>();
        
        // Enqueue Operations
        queue.offer(10);
        queue.offer(20);
        queue.offer(30);
        
        System.out.println("Queue: " + queue);
        System.out.println("Front Element: " + queue.peek()); // 10
        
        // Dequeue Operation
        int dequeued = queue.poll(); // Removes 10
        System.out.println("Dequeued: " + dequeued);
        System.out.println("Queue after dequeue: " + queue);
        
        // Practical Application: Breadth-First Search
        Graph graph = createSampleGraph();
        List<Integer> bfsResult = bfs(graph, 0);
        System.out.println("BFS Traversal: " + bfsResult);
    }
    
    // BFS with Queue
    public static List<Integer> bfs(Graph graph, int startNode) {
        List<Integer> result = new ArrayList<>();
        boolean[] visited = new boolean[graph.getVertexCount()];
        Queue<Integer> queue = new LinkedList<>();
        
        visited[startNode] = true;
        queue.offer(startNode);
        
        while (!queue.isEmpty()) {
            int current = queue.poll();
            result.add(current);
            
            for (int neighbor : graph.getNeighbors(current)) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    queue.offer(neighbor);
                }
            }
        }
        
        return result;
    }
    
    private static Graph createSampleGraph() {
        // Implementation for sample graph
        return new Graph(6);
    }
}

Queue Implementation

public class ArrayQueue<T> {
    private Object[] data;
    private int front;
    private int rear;
    private int size;
    private int capacity;
    
    public ArrayQueue() {
        this.capacity = 10;
        this.data = new Object[capacity];
        this.front = 0;
        this.rear = -1;
        this.size = 0;
    }
    
    public void enqueue(T element) {
        if (isFull()) {
            resize();
        }
        rear = (rear + 1) % capacity;
        data[rear] = element;
        size++;
    }
    
    @SuppressWarnings("unchecked")
    public T dequeue() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        
        T element = (T) data[front];
        front = (front + 1) % capacity;
        size--;
        return element;
    }
    
    @SuppressWarnings("unchecked")
    public T peek() {
        if (isEmpty()) {
            throw new NoSuchElementException();
        }
        return (T) data[front];
    }
    
    public boolean isEmpty() {
        return size == 0;
    }
    
    public boolean isFull() {
        return size == capacity;
    }
    
    private void resize() {
        int newCapacity = capacity * 2;
        Object[] newData = new Object[newCapacity];
        
        for (int i = 0; i < size; i++) {
            newData[i] = data[(front + i) % capacity];
        }
        
        data = newData;
        front = 0;
        rear = size - 1;
        capacity = newCapacity;
    }
    
    public int size() {
        return size;
    }
}

Heap (Heap)

Priority Queue

Heaps are special tree structures for Priority Queues.

public class HeapDemo {
    public static void main(String[] args) {
        // Min-Heap (Priority Queue)
        PriorityQueue<Integer> minHeap = new PriorityQueue<>();
        minHeap.offer(50);
        minHeap.offer(20);
        minHeap.offer(30);
        minHeap.offer(10);
        minHeap.offer(40);
        
        System.out.println("Min-Heap: " + minHeap);
        System.out.println("Smallest element: " + minHeap.peek()); // 10
        
        System.out.println("Elements in order:");
        while (!minHeap.isEmpty()) {
            System.out.print(minHeap.poll() + " "); // 10 20 30 40 50
        }
        
        // Max-Heap
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
        maxHeap.offer(50);
        maxHeap.offer(20);
        maxHeap.offer(30);
        maxHeap.offer(10);
        maxHeap.offer(40);
        
        System.out.println("\nMax-Heap: " + maxHeap);
        System.out.println("Largest element: " + maxHeap.peek()); // 50
        
        // Heap Sort
        int[] array = {50, 20, 30, 10, 40};
        heapSort(array);
        System.out.println("Heap Sort result: " + Arrays.toString(array));
    }
    
    // Heap Sort Algorithm
    public static void heapSort(int[] array) {
        int n = array.length;
        
        // Build max heap
        for (int i = n / 2 - 1; i >= 0; i--) {
            heapify(array, n, i);
        }
        
        // Extract elements from heap
        for (int i = n - 1; i > 0; i--) {
            // Move current root to end
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            
            // heapify root element
            heapify(array, i, 0);
        }
    }
    
    private static void heapify(int[] array, int n, int i) {
        int largest = i;
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        
        if (left < n && array[left] > array[largest]) {
            largest = left;
        }
        
        if (right < n && array[right] > array[largest]) {
            largest = right;
        }
        
        if (largest != i) {
            int swap = array[i];
            array[i] = array[largest];
            array[largest] = swap;
            
            heapify(array, n, largest);
        }
    }
}

Min-Heap Implementation

public class MinHeap<T extends Comparable<T>> {
    private List<T> heap;
    
    public MinHeap() {
        this.heap = new ArrayList<>();
    }
    
    public void insert(T element) {
        heap.add(element);
        heapifyUp(heap.size() - 1);
    }
    
    public T extractMin() {
        if (heap.isEmpty()) {
            throw new NoSuchElementException();
        }
        
        T min = heap.get(0);
        T last = heap.remove(heap.size() - 1);
        
        if (!heap.isEmpty()) {
            heap.set(0, last);
            heapifyDown(0);
        }
        
        return min;
    }
    
    public T peek() {
        if (heap.isEmpty()) {
            throw new NoSuchElementException();
        }
        return heap.get(0);
    }
    
    private void heapifyUp(int index) {
        while (index > 0) {
            int parentIndex = (index - 1) / 2;
            if (heap.get(index).compareTo(heap.get(parentIndex)) >= 0) {
                break;
            }
            
            swap(index, parentIndex);
            index = parentIndex;
        }
    }
    
    private void heapifyDown(int index) {
        int size = heap.size();
        
        while (true) {
            int leftChild = 2 * index + 1;
            int rightChild = 2 * index + 2;
            int smallest = index;
            
            if (leftChild < size && heap.get(leftChild).compareTo(heap.get(smallest)) < 0) {
                smallest = leftChild;
            }
            
            if (rightChild < size && heap.get(rightChild).compareTo(heap.get(smallest)) < 0) {
                smallest = rightChild;
            }
            
            if (smallest == index) {
                break;
            }
            
            swap(index, smallest);
            index = smallest;
        }
    }
    
    private void swap(int i, int j) {
        T temp = heap.get(i);
        heap.set(i, heap.get(j));
        heap.set(j, temp);
    }
    
    public boolean isEmpty() {
        return heap.isEmpty();
    }
    
    public int size() {
        return heap.size();
    }
}

Tree Structures

Binary Search Tree

public class BinarySearchTree<T extends Comparable<T>> {
    private class Node {
        T data;
        Node left;
        Node right;
        
        Node(T data) {
            this.data = data;
            this.left = null;
            this.right = null;
        }
    }
    
    private Node root;
    
    public void insert(T data) {
        root = insert(root, data);
    }
    
    private Node insert(Node node, T data) {
        if (node == null) {
            return new Node(data);
        }
        
        if (data.compareTo(node.data) < 0) {
            node.left = insert(node.left, data);
        } else if (data.compareTo(node.data) > 0) {
            node.right = insert(node.right, data);
        }
        
        return node;
    }
    
    public boolean search(T data) {
        return search(root, data);
    }
    
    private boolean search(Node node, T data) {
        if (node == null) {
            return false;
        }
        
        if (data.compareTo(node.data) == 0) {
            return true;
        } else if (data.compareTo(node.data) < 0) {
            return search(node.left, data);
        } else {
            return search(node.right, data);
        }
    }
    
    public void inorderTraversal() {
        inorderTraversal(root);
        System.out.println();
    }
    
    private void inorderTraversal(Node node) {
        if (node != null) {
            inorderTraversal(node.left);
            System.out.print(node.data + " ");
            inorderTraversal(node.right);
        }
    }
    
    public void preorderTraversal() {
        preorderTraversal(root);
        System.out.println();
    }
    
    private void preorderTraversal(Node node) {
        if (node != null) {
            System.out.print(node.data + " ");
            preorderTraversal(node.left);
            preorderTraversal(node.right);
        }
    }
    
    public void postorderTraversal() {
        postorderTraversal(root);
        System.out.println();
    }
    
    private void postorderTraversal(Node node) {
        if (node != null) {
            postorderTraversal(node.left);
            postorderTraversal(node.right);
            System.out.print(node.data + " ");
        }
    }
    
    public int height() {
        return height(root);
    }
    
    private int height(Node node) {
        if (node == null) {
            return 0;
        }
        
        int leftHeight = height(node.left);
        int rightHeight = height(node.right);
        
        return Math.max(leftHeight, rightHeight) + 1;
    }
    
    public T findMin() {
        if (root == null) {
            throw new NoSuchElementException();
        }
        
        Node current = root;
        while (current.left != null) {
            current = current.left;
        }
        
        return current.data;
    }
    
    public T findMax() {
        if (root == null) {
            throw new NoSuchElementException();
        }
        
        Node current = root;
        while (current.right != null) {
            current = current.right;
        }
        
        return current.data;
    }
}

Tree Traversal Demo

public class TreeTraversalDemo {
    public static void main(String[] args) {
        BinarySearchTree<Integer> bst = new BinarySearchTree<>();
        
        // Insert
        bst.insert(50);
        bst.insert(30);
        bst.insert(70);
        bst.insert(20);
        bst.insert(40);
        bst.insert(60);
        bst.insert(80);
        
        System.out.print("In-Order: ");
        bst.inorderTraversal(); // 20 30 40 50 60 70 80
        
        System.out.print("Pre-Order: ");
        bst.preorderTraversal(); // 50 30 20 40 70 60 80
        
        System.out.print("Post-Order: ");
        bst.postorderTraversal(); // 20 40 30 60 80 70 50
        
        System.out.println("Tree height: " + bst.height()); // 3
        System.out.println("Minimum: " + bst.findMin()); // 20
        System.out.println("Maximum: " + bst.findMax()); // 80
        
        // Search
        System.out.println("40 found: " + bst.search(40)); // true
        System.out.println("90 found: " + bst.search(90)); // false
    }
}

Graphs

Graph Representations

public class Graph {
    private int vertexCount;
    private List<List<Integer>> adjacencyList;
    
    public Graph(int vertexCount) {
        this.vertexCount = vertexCount;
        this.adjacencyList = new ArrayList<>();
        
        for (int i = 0; i < vertexCount; i++) {
            adjacencyList.add(new ArrayList<>());
        }
    }
    
    // Directed graph
    public void addEdge(int source, int destination) {
        if (source >= 0 && source < vertexCount && 
            destination >= 0 && destination < vertexCount) {
            adjacencyList.get(source).add(destination);
        }
    }
    
    // Undirected graph
    public void addUndirectedEdge(int source, int destination) {
        addEdge(source, destination);
        addEdge(destination, source);
    }
    
    public List<Integer> getNeighbors(int vertex) {
        if (vertex >= 0 && vertex < vertexCount) {
            return new ArrayList<>(adjacencyList.get(vertex));
        }
        return new ArrayList<>();
    }
    
    public int getVertexCount() {
        return vertexCount;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < vertexCount; i++) {
            sb.append(i).append(": ");
            for (int neighbor : adjacencyList.get(i)) {
                sb.append(neighbor).append(" ");
            }
            sb.append("\n");
        }
        return sb.toString();
    }
}

Graph Algorithms

public class GraphAlgorithms {
    
    // Depth-First Search (DFS)
    public static List<Integer> dfs(Graph graph, int startNode) {
        List<Integer> result = new ArrayList<>();
        boolean[] visited = new boolean[graph.getVertexCount()];
        dfsHelper(graph, startNode, visited, result);
        return result;
    }
    
    private static void dfsHelper(Graph graph, int node, boolean[] visited, List<Integer> result) {
        visited[node] = true;
        result.add(node);
        
        for (int neighbor : graph.getNeighbors(node)) {
            if (!visited[neighbor]) {
                dfsHelper(graph, neighbor, visited, result);
            }
        }
    }
    
    // Breadth-First Search (BFS)
    public static List<Integer> bfs(Graph graph, int startNode) {
        List<Integer> result = new ArrayList<>();
        boolean[] visited = new boolean[graph.getVertexCount()];
        Queue<Integer> queue = new LinkedList<>();
        
        visited[startNode] = true;
        queue.offer(startNode);
        
        while (!queue.isEmpty()) {
            int current = queue.poll();
            result.add(current);
            
            for (int neighbor : graph.getNeighbors(current)) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;
                    queue.offer(neighbor);
                }
            }
        }
        
        return result;
    }
    
    // Dijkstra's Algorithm (shortest paths)
    public static Map<Integer, Integer> dijkstra(int[][] graph, int startNode) {
        int n = graph.length;
        int[] distances = new int[n];
        boolean[] visited = new boolean[n];
        Arrays.fill(distances, Integer.MAX_VALUE);
        distances[startNode] = 0;
        
        PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[1]));
        pq.offer(new int[]{startNode, 0});
        
        while (!pq.isEmpty()) {
            int[] current = pq.poll();
            int node = current[0];
            int distance = current[1];
            
            if (visited[node]) continue;
            visited[node] = true;
            
            for (int neighbor = 0; neighbor < n; neighbor++) {
                if (graph[node][neighbor] > 0 && !visited[neighbor]) {
                    int newDistance = distance + graph[node][neighbor];
                    if (newDistance < distances[neighbor]) {
                        distances[neighbor] = newDistance;
                        pq.offer(new int[]{neighbor, newDistance});
                    }
                }
            }
        }
        
        Map<Integer, Integer> result = new HashMap<>();
        for (int i = 0; i < n; i++) {
            if (distances[i] != Integer.MAX_VALUE) {
                result.put(i, distances[i]);
            }
        }
        
        return result;
    }
    
    // Topological Sort
    public static List<Integer> topologicalSort(Graph graph) {
        int n = graph.getVertexCount();
        int[] inDegree = new int[n];
        
        // Calculate in-degree
        for (int i = 0; i < n; i++) {
            for (int neighbor : graph.getNeighbors(i)) {
                inDegree[neighbor]++;
            }
        }
        
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            if (inDegree[i] == 0) {
                queue.offer(i);
            }
        }
        
        List<Integer> result = new ArrayList<>();
        while (!queue.isEmpty()) {
            int current = queue.poll();
            result.add(current);
            
            for (int neighbor : graph.getNeighbors(current)) {
                inDegree[neighbor]--;
                if (inDegree[neighbor] == 0) {
                    queue.offer(neighbor);
                }
            }
        }
        
        return result;
    }
}

Graph Demo

public class GraphDemo {
    public static void main(String[] args) {
        // Create graph
        Graph graph = new Graph(6);
        
        // Add edges
        graph.addEdge(0, 1);
        graph.addEdge(0, 2);
        graph.addEdge(1, 3);
        graph.addEdge(2, 4);
        graph.addEdge(3, 5);
        graph.addEdge(4, 5);
        
        System.out.println("Graph:");
        System.out.println(graph);
        
        // Traversals
        System.out.println("DFS: " + GraphAlgorithms.dfs(graph, 0));
        System.out.println("BFS: " + GraphAlgorithms.bfs(graph, 0));
        
        // Dijkstra's Algorithm
        int[][] weightedGraph = {
            {0, 4, 2, 0, 0, 0},
            {4, 0, 1, 5, 0, 0},
            {2, 1, 0, 8, 10, 0},
            {0, 5, 8, 0, 2, 6},
            {0, 0, 10, 2, 0, 3},
            {0, 0, 0, 6, 3, 0}
        };
        
        Map<Integer, Integer> shortestPaths = GraphAlgorithms.dijkstra(weightedGraph, 0);
        System.out.println("Shortest paths from node 0: " + shortestPaths);
        
        // Topological sort for DAG
        Graph dag = new Graph(4);
        dag.addEdge(0, 1);
        dag.addEdge(0, 2);
        dag.addEdge(1, 3);
        dag.addEdge(2, 3);
        
        List<Integer> topologicalOrder = GraphAlgorithms.topologicalSort(dag);
        System.out.println("Topological order: " + topologicalOrder);
    }
}

Complexity Analysis

Time Complexity Comparison

Data StructureAccessInsertDeleteSearch
ArrayO(1)O(n)O(n)O(n)
Dynamic ArrayO(1)O(1)*O(n)O(n)
Linked ListO(n)O(1)*O(1)*O(n)
StackO(1)O(1)O(1)O(n)
QueueO(1)O(1)O(1)O(n)
Binary Search TreeO(log n)*O(log n)*O(log n)*O(log n)*
HeapO(1)O(log n)O(log n)O(n)
Hash TableO(1)*O(1)*O(1)*O(1)*

*Amortized complexity or average case

Space Complexity

Data StructureMemoryRemarks
ArrayO(n)Fixed size
Dynamic ArrayO(n)With overhead
Linked ListO(n)Additional pointers
Binary Search TreeO(n)Recursive structure
GraphO(V + E)V = vertices, E = edges

Best Practices

1. Choose the right data structure

// Frequent search operations -> HashSet/HashMap
Set<String> uniqueNames = new HashSet<>();
Map<String, Integer> wordCount = new HashMap<>();

// Ordered data -> TreeSet/TreeMap
Set<Integer> sortedNumbers = new TreeSet<>();
Map<String, Integer> sortedWordCount = new TreeMap<>();

// FIFO processing -> Queue
Queue<Task> taskQueue = new LinkedList<>();

// LIFO processing -> Stack
Stack<Operation> undoStack = new Stack<>();

// Priority processing -> PriorityQueue
PriorityQueue<Event> eventQueue = new PriorityQueue<>();

2. Performance Considerations

// Bad: O(n²) for large datasets
List<Integer> list = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
    for (int j = 0; j < list.size(); j++) {
        // O(n²) operation
    }
}

// Good: O(n) with HashSet
Set<Integer> set = new HashSet<>();
for (int item : list) {
    set.add(item); // O(1) on average
}

Exam-Relevant Questions

Typical Tasks

  1. Implement a Stack with Array
  2. Compare BFS and DFS
  3. Explain Heap Sort
  4. Implement Binary Search
  5. Calculate the complexity of algorithms

Important Concepts

  • Amortized Analysis: Average cost over operations
  • Best-Case/Worst-Case/Average-Case: Different scenarios
  • Space-Time Tradeoff: Memory vs. speed
  • Recursion vs Iteration: Implementation variants

Summary

Data structures are fundamental for efficient algorithms:

  • Arrays: Direct access, fixed size
  • Stack/Queue: Special access orders
  • Heaps: Priority queues, efficient min/max operations
  • Trees: Hierarchical organization, efficient searching
  • Graphs: Network relationships, complex algorithms

Choosing the right data structure is crucial for performance and significantly affects the complexity of operations.

Back to Blog
Share:

Related Posts