跳至主要內容

排序算法

约 492 字

排序算法

快速排序

核心思想

首先检查数组长度,如果数组长度小于等于1,那么直接返回,不需要排序。否则,选择数组中间的一个元素作为基准值,遍历数组,将小于基准值的元素放在左边,大于基准值的元素放在右边,然后递归地对左右两边的数组进行排序。

// npm run code src/code/algorithm/quick-sort.ts

export {};

function quickSort(arr: number[]): number[] {
    if (arr.length <= 1) {
        return arr;
    }

    const pivot = arr[0];
    const left: number[] = [];
    const right: number[] = [];

    for (let i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }

    return [...quickSort(left), pivot, ...quickSort(right)];
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = quickSort(array);
console.log("Sorted array:", sortedArray);

归并排序

核心思想

首先检查数组长度,如果数组长度小于等于1,那么直接返回,不需要排序。否则,将数组分成两半,并递归地调用自身来排序这两部分,然后将两个有序的数组合并成一个有序的数组。

// npm run code src/code/algorithm/merge-sort.ts

export { };

function mergeSort(arr: number[]): number[] {
    if (arr.length <= 1) {
        return arr;
    }

    const middle = Math.floor(arr.length / 2);
    const left = arr.slice(0, middle);
    const right = arr.slice(middle);

    return merge(mergeSort(left), mergeSort(right));
}

function merge(left: number[], right: number[]): number[] {
    let result: number[] = [];
    let leftIndex = 0;
    let rightIndex = 0;

    while (leftIndex < left.length && rightIndex < right.length) {
        if (left[leftIndex] < right[rightIndex]) {
            result.push(left[leftIndex]);
            leftIndex++;
        } else {
            result.push(right[rightIndex]);
            rightIndex++;
        }
    }

    return result.concat(left.slice(leftIndex)).concat(right.slice(rightIndex));
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = mergeSort(array);
console.log("Sorted array:", sortedArray);

堆排序

核心思想

// npm run code src/code/algorithm/heapsort.ts

export { };

class MaxHeap {
    private heap: number[];

    constructor() {
        this.heap = [];
    }

    private getParentIndex(i: number): number {
        return Math.floor((i - 1) / 2);
    }

    private getLeftChildIndex(i: number): number {
        return 2 * i + 1;
    }

    private getRightChildIndex(i: number): number {
        return 2 * i + 2;
    }

    private swap(i: number, j: number) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
    }

    public insert(key: number) {
        this.heap.push(key);
        let index = this.heap.length - 1;
        while (index !== 0 && this.heap[this.getParentIndex(index)] < this.heap[index]) {
            this.swap(this.getParentIndex(index), index);
            index = this.getParentIndex(index);
        }
    }

    public extractMax(): number | null {
        if (this.heap.length === 0) return null;
        if (this.heap.length === 1) return this.heap.pop()!;

        const max = this.heap[0];
        this.heap[0] = this.heap.pop()!;
        this.heapify(0);

        return max;
    }

    private heapify(i: number) {
        const left = this.getLeftChildIndex(i);
        const right = this.getRightChildIndex(i);
        let largest = i;

        if (left < this.heap.length && this.heap[left] > this.heap[largest]) {
            largest = left;
        }

        if (right < this.heap.length && this.heap[right] > this.heap[largest]) {
            largest = right;
        }

        if (largest !== i) {
            this.swap(i, largest);
            this.heapify(largest);
        }
    }
}

function heapSort(arr: number[]): number[] {
    let heap = new MaxHeap();
    for (let num of arr) {
        heap.insert(num);
    }

    for (let i = arr.length - 1; i >= 0; i--) {
        arr[i] = heap.extractMax()!;
    }

    return arr;
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = heapSort(array);
console.log("Sorted array:", sortedArray);

冒泡排序

核心思想

遍历数组,比较相邻的两个元素,如果前一个元素大于后一个元素,那么交换这两个元素的位置,然后继续遍历,直到没有元素需要交换。

// npm run code src/code/algorithm/bubble-sort.ts

export { };

function bubbleSort(arr: number[]): number[] {
    let n = arr.length;
    let swapped: boolean;

    do {
        swapped = false;
        for (let i = 1; i < n; i++) {
            if (arr[i - 1] > arr[i]) {
                [arr[i - 1], arr[i]] = [arr[i], arr[i - 1]]; // 交换元素
                swapped = true;
            }
        }
        n--;
    } while (swapped);

    return arr;
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = bubbleSort(array);
console.log("Sorted array:", sortedArray);

选择排序

核心思想

首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。

// npm run code src/code/algorithm/selection-sort.ts

export { };

function selectionSort(arr: number[]): number[] {
    for (let i = 0; i < arr.length - 1; i++) {
        let minIndex = i;
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        }
        if (minIndex !== i) {
            [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]]; // 交换元素
        }
    }
    return arr;
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = selectionSort(array);
console.log("Sorted array:", sortedArray);

希尔排序

核心思想

希尔排序首先设定一个“间隔”,开始时为数组长度的一半,对每个间隔内的元素进行插入排序,然后将间隔减半,再进行插入排序,直到间隔为1,此时的插入排序已经是对整个数组进行排序了。

// npm run code src/code/algorithm/shell-sort.ts

export { };

function shellSort(arr: number[]): number[] {
    let n = arr.length;
    for (let gap = Math.floor(n / 2); gap > 0; gap = Math.floor(gap / 2)) {
        for (let i = gap; i < n; i += 1) {
            let temp = arr[i];
            let j;
            for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) {
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
    return arr;
}

// 示例
const array = [3, 6, 8, 10, 1, 2, 1];
console.log("Original array:", array);
const sortedArray = shellSort(array);
console.log("Sorted array:", sortedArray);

上次编辑于: