常见排序算法和查找算法

1、冒泡排序

时间复杂度:o(n^2),稳定

  • 对未排序的各元素从头到尾依次比较相邻的两个元素大小关系
  • 如果左边的队员高, 则两队员交换位置
  • 向右移动一个位置, 比较下面两个队员
  • 当走到最右端时, 最高的队员一定被放在了最右边
  • 按照这个思路, 从最左端重新开始, 这次走到倒数第二个位置的队员即可.
  • 依次类推, 就可以将数据排序完成
let arr = [3, 15, 9, 10, 1, 26, 2, 5];
for (let i = 0; i < arr.length - 1; i++) { 
    for (let j=0; j < arr.length - 1 - i;j++) { 
        if (arr[j]> arr[j + 1]) {
            let temp = arr[j];
            arr[j] = arr[j + 1];
      	    arr[j + 1] = temp;
        }
    }
}
console.log(arr);        //[1, 2, 3, 5, 9, 10, 15, 26]

2、选择排序

时间复杂度:o(n^2),不稳定

  • 选定第一个索引位置,然后和后面元素依次比较
  • 如果后面的队员, 小于第一个索引位置的队员, 则交换位置
  • 经过一轮的比较后, 可以确定第一个位置是最小的
  • 然后使用同样的方法把剩下的元素逐个比较即可
  • 可以看出选择排序,第一轮会选出最小值,第二轮会选出第二小的值,直到最后
let arr = [3, 15, 9, 10, 1, 26, 2, 5];
for (let i = 0; i < arr.length - 1; i++) { 
    let min = i;
    for (let j = i + 1; j < arr.length; j++) {
        if (arr[min] > arr[j]) {
            min = j;
        }
    }
    if (min != i) {
        let temp = arr[min];
        arr[min] = arr[i];
        arr[i] = temp;
    }
}
console.log(arr);        //[1, 2, 3, 5, 9, 10, 15, 26]

3、插入排序

时间复杂度:o(n^2),稳定

  • 从第一个元素开始,该元素可以认为已经被排序
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置
  • 重复上一个步骤,直到找到已排序的元素小于或者等于新元素的位置
  • 将新元素插入到该位置后, 重复上面的步骤.
let arr = [3, 15, 9, 10, 1, 26, 2, 5];
for (let i = 0; i < arr.length - 1; i++) { 
    let j = i + 1;
    let temp = arr[j];
    while (j > 0 && arr[j - 1] > temp) {
        arr[j] = arr[j - 1];
        j--;
    }
    arr[j] = temp;
}
console.log(arr);        //[1, 2, 3, 5, 9, 10, 15, 26]

4、希尔排序

时间复杂度:o(n^1.3),不稳定

let arr = [3, 15, 9, 10, 1, 26, 2, 5]
let length = arr.length;
let gap = Math.floor(length / 2); //增量
while (gap >= 1) {
    for (let i = 0; i < length - gap; i++) {
        let j = i + gap;
        let temp = arr[j];
        while (j > gap - 1 && arr[j - gap] > temp) {
            arr[j] = arr[j - gap];
            j -= gap;
        }
        arr[j] = temp;
    }
    gap = Math.floor(gap / 2);
}
console.log(arr);        //[1, 2, 3, 5, 9, 10, 15, 26]

5、归并排序

时间复杂度:o(nlog2n),稳定

基本思想与过程:先递归的分解数列再合并数列(分治思想的典型应用)

(1)将一个数组拆成A、B两个小组,两个小组继续拆,直到每个小组只有一个元素为止。

  (2)按照拆分过程逐步合并小组,由于各小组初始只有一个元素,可以看做小组内部是有序的,合并小组可以被看做是合并两个有序数组的过程。

  (3)对左右两个小数列重复第二步,直至各区间只有1个数。

  下面对数组【42,20,17,13,28,14,23,15】进行归并排序,模拟排序过程如下:

  第一步:拆分数组,一共需要拆分三次(logN);

    第一次拆成【42,20,17,13】,【28,14,23,15】,

    第二次拆成【42,20】,【17,13】,【28,14】,【23,15】,、

    第三次拆成【42】,【20】,【17】,【13】,【28】,【14】,【23】,【15】;

  第二步:逐步归并数组,采用合并两个有序数组的方法,每一步其算法复杂度基本接近于O(N)

    第一次归并为【20,42】,【13,17】,【14,28】,【15,23】

    第二次归并为【13,17,20,42】,【14,15,23,28】,

    第三次归并为【13, 14, 15, 17, 20, 23, 28, 42】

let arr = [3, 15, 9, 10, 1, 26, 2, 5]
//分数组
function mergeSort() {
    arr = merge_1(arr);
    console.log(arr)
}
//分数组
function merge_1(arr) {
    let length = arr.length;
    if (length > 1) {
        let index = Math.floor(length / 2);
        let left = arr.slice(0, index);
        let right = arr.slice(index);
        return merge_2(merge_1(left), merge_1(right));
    } else {
        return arr;
    }
}
//合数组
function merge_2(leftArr, rightArr) {
    let mergeArr = [];
    while (leftArr.length != 0 && rightArr.length != 0) {
        if (leftArr[0] > rightArr[0]) {
            mergeArr.push(rightArr.shift());
        } else {
            mergeArr.push(leftArr.shift());
        }
    }
    return mergeArr.concat(leftArr, rightArr);
}
mergeSort()

6、快速排序

时间复杂度:o(nlog2n),不稳定

let arr = [3, 15, 9, 10, 1, 26, 2, 5]
function quickSort() {
    arr = quick(arr);
    console.log(arr)
}
function quick(arr) {
    let length = arr.length;
    if (length <= 1) {
        return arr;
    }
    let pivotIndex = Math.floor(length / 2); //找基准下标
    let pivot = arr.splice(pivotIndex, 1)[0]; //找基准
    let left = [];
    let right = [];
    for (let i in arr) {
        let e = arr[i];
        if (e < pivot) {
            left.push(e);
        } else {
            right.push(e);
        }
    }
    return quick(left).concat(pivot, quick(right));
}
quickSort()

7、二分查找

let arr = [1, 2, 3, 5, 9, 10, 15, 26]
function BinarySearch(key) {
    let min = 0;
    let max = arr.length - 1;
    while (min <= max) { 
        let mid=Math.floor((min + max) / 2); 
        if (key==arr[mid]) { 
            return mid; 
        } else { 
            if (key < arr[mid]) { 
                max=mid - 1; 
            } else { min=mid + 1; } 
        } 
    } 
    return -1; 
} 
let a=BinarySearch(5); 
console.log(a); //3

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值