Sorting algorithms

Bubble sort

In an unordered array, starting from the beginning, if the current value is greater than the next value, we swap them, and then move to the next value and repeat the process. After each iteration, the biggest value is always at the end, and we can start over without including the last n values.

export default function bubble_sort(arr: number[]): void {
    for (let i = 0; i < arr.length ; i++) {
        for (let j = 0; j < arr.length - 1 - i; j++) {
            if(arr[j] > arr[j + 1]) {
                const tmp = arr[j]
                arr[j] = arr[j + 1]
                arr[j + 1] = tmp
            }
        }
    }
}

In this example:

This Big O for this algorithm is O(n²).

Queue

A queue is a specific implementation of a linked list.

A queue is FIFO structure, for First I, First Out. It's like a real life queue or line, where a new entrant gets in the queue through its end. And if we want to remove an entry, we remove the first in the queue.

There are usually three operations associated with a queue:

Enqueue
Adding to the queue through its tail
Deque
Removing from the queue through its head
Peek
Seeing what is the first element of the queue

Example:

type Node<T> = {
    value: T,
    next?: Node<T>,
}
 
export default class Queue<T> {
    public length: number;
    private head?: Node<T>
    private tail?: Node<T>
 
    constructor() {
        this.head = this.tail = undefined
        this.length = 0
    }
 
    enqueue(item: T): void {
        const node = {value:item} as Node<T>
        this.length++
        if(!this.tail) {
            this.tail = this.head = node
            return
        }
 
        this.tail.next = node
        this.tail = node
    }
 
    deque(): T | undefined {
        if(!this.head) {
            return undefined
        }
 
        this.length--
 
        const head = this.head
        this.head = this.head.next
        return head.value
    }
 
    peek(): T | undefined {
        return this.head?.value
    }
}

Stack

A stack is a specific implementation of a linked list.

A queue is LIFO structure, for Last I, First Out. It's like a real life stack of plates, where a new entrant gets in the stack through its head. And if we want to remove an entry, we remove the last in the queue.

There are usually three operations associated with a queue:

Push
Adding to the stack through its head
Pop
Removing from the stack through its tail
Peek
Seeing what is the first element of the stack

Example:

type Node<T> = {
    value: T,
    prev?: Node<T>
}
 
export default class Stack<T> {
    public length: number;
    private head?: Node<T>
 
    constructor() {
        this.head = undefined
        this.length = 0
    }
 
    push(item: T): void {
        const node = { value: item } as Node<T>
 
        this.length++
        if (!this.head) {
            this.head = node
            return
        }
        node.prev = this.head
        this.head = node
    }
 
    pop(): T | undefined {
        this.length = Math.max(0, this.length - 1)
        if (this.length === 0) {
            const head = this.head
            this.head = undefined
            return head?.value
        }
        const head = this.head as Node<T>
        this.head = head.prev
        return head.value
    }
 
    peek(): T | undefined {
        return this.head?.value
    }
}

Initially published: October 17th, 2022
Generated: November 10th, 2022