js三种常见的排序方式 - 冒泡排序,快速排序,堆排序

175 阅读1分钟
// 交换函数
function swap(arr, x, y){
    let temp = arr[x];
    arr[x] = arr[y];
    arr[y] = temp;
}

// 冒泡排序
function bubbleSort(arr){
    for(let i=0; i<arr.length-1; ++i){
        for(let j=0; j<arr.length-i-1; ++j){
            if(arr[j] > arr[j+1]) swap(arr, j, j+1)
        }
    }
}

// 快速排序
function quickSort(arr, left, right){
    if(left >= right) return;
    function partition(arr, left, right){
        let k = arr[left];
        while(left < right){
            while(arr[right] >= k && left < right) --right;
            swap(arr, left, right);
            while(arr[left] < k && left < right) ++left;
            swap(arr, left, right);
        }
        arr[left] = k;
        return left;
    }
    const pos = partition(arr, left, right);
    quickSort(arr, left, pos-1);
    quickSort(arr, pos+1, right);
}

// 堆排序
function heapSort(arr){
    // 建堆
    function buildHeap(arr){
        let heapSize = arr.length;
        // 从最后的非叶子节点开始,创建大顶堆,满二叉树中最后一个非叶子节点为(n/2-1),n为二叉树的节点数
        // 从下往上遍历是为了让堆顶元素为最大或最小数,
        for(let i=Math.floor(heapSize / 2 - 1); i>=0; --i){
            heapify(arr, i, heapSize);
        }
    }
    function heapify(arr, index, heapSize){
        while(true){
            let minIndex = index;
            // 先跟左叶子节点比较
            if(2*index + 1 < heapSize && arr[2*index + 1] > arr[minIndex]){
                minIndex = 2*index + 1; 
            }
            // 再跟右叶子节点比较
            if(2*(index + 1) < heapSize && arr[2*(index + 1)] > arr[minIndex]){
                minIndex = 2*(index + 1);
            }
            // 如果当前节点比左右节点都大,则不需要进行操作
            if(minIndex === index) return;
            // 将当前节点与左右节点中较大的进行交换
            swap(arr, minIndex, index);
            // 将交换了的节点也进行heapify,保证节点会比左右叶子节点大
            index = minIndex;
        }
    }
    // 调用建堆函数
    buildHeap(arr);
    // 大顶堆排序,在建堆的时候,只保证了根节点会大于叶子节点
    // 不断地将根节点移到数组的最后面,再对剩余的节点进行堆化
    for(let i=arr.length-1; i>=0; --i){
        swap(arr, 0, i);
        heapify(arr, 0, i)  
    }
}