前端排序算法

常见排序算法有插入排序、冒泡排序、选择排序、快速排序、归并排序、堆排序。以下是我对这些排序的理解和代码实现

1.插入排序

按从左到右的顺序,从下标为1的数开始与前一个进行比较,小则往前移,大则退出循环。

let array = [1, 9, 3, 5, 2, 3, 5, 7, 2];

        function arrayInsert(array) {
            for (let i = 1; i < array.length; i++) {
                let target = i;
                console.log("array" + i, array[i]);
                for (let j = i - 1; j >= 0; j--) {
                    console.log("array" + j, array[j]);
                    if (array[target] < array[j]) {   //target目的:在排序一次后还能接着比较排序
                        let temp;
                        temp = array[target];
                        array[target] = array[j];
                        array[j] = temp;
                        target = j;
                    } else {
                        break;
                    }

                }
            }
            return array;
        }
        //输出
        let array1 = arrayInsert(array);
        for (let i = 0; i < array.length; i++) {

            console.log(array1[i]);
        }

        //结果如预期 1 2 2 3 3 5 5 7 9

2.冒泡排序

将数组从第一个开始,与后面相邻的数比较,如果这个数比后面相邻的数大,则交换位置。(向上冒泡),这一个数比较完成之后,最后那个数应该为最大的数。
接着循环第二个数,已经排好的不参与循环。
直至所有数排好完毕。
考虑当一次循环没有发生冒泡,说明已经排序完成,停止循环。

        let array = [1, 9, 3, 5, 2, 3, 5, 7, 2];

        function bubbleInsert(array) {
            for (let i = 0; i < array.length; i++) {
                let target = true;
                console.log("arraybefore", array);
                for (let j = 0; j < array.length - 1 - i; j++) {
                    console.log("arrayafter", array);
                    if (array[j] > array[j + 1]) { //看是否比后一个数大
                        let temp;
                        temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        target = false;
                    }
                }
                if (target) {       //如果没有改变target值,则表示数组已经完成冒泡排序,或者传入的数组是排好序的。
                    break;
                }
            }

            return array;
        }
        //输出
        let array1 = bubbleInsert(array);
        for (let k = 0; k < array.length; k++) {
            console.log(array1[k]);
        }

结果如上。

3.选择排序

两层循环,第一次循环找出最小那个出赋值给array0,第二次循环找出第二小的那个数赋值给array1,依次类推,直至全部排序完毕。
版本一:(错误)

        let array = [1, 9, 3, 5, 2, 3, 5, 7, 2];

        function selectionSort(array) {
            for (let i = 0; i < array.length; i++) {
                let target = i; //假设首次最小是下标为i的数,因为默认小的放在了前面
                console.log("arraybefore", array);
                for (let j = i + 1; j < array.length; j++) {
                    if (array[j + 1] < array[j]) { //比较哪个大
                        let temp;
                        temp = array[j];
                        array[j] = array[j + 1];
                        array[j + 1] = temp;
                        target = j;
                    }
                    console.log("arrayafter", array);
                }
            }

            return array;
        }
        //输出
        let array1 = selectionSort(array);
        for (let k = 0; k < array.length; k++) {
            console.log(array1[k]);
        }

结果:
错误结果
我们可以看见这是有问题的,代码只选择小的数往前推,并没有判断是否比之前的更小。

版本二:(正确)

        let array = [1, 9, 3, 5, 2, 3, 5, 7, 2];

        function selectionSort(array) {
            for (let i = 0; i < array.length; i++) {
                let target = i; //假设首次最小是下标为i的数,因为默认小的放在了前面
                console.log("arraybefore", array);
                for (let j = i + 1; j < array.length; j++) {
                    if (array[j] < array[target]) { //比较哪个大
                        target = j;
                    }
                }
                //把最小的赋给前头
                let temp;
                temp = array[target];
                array[target] = array[i];
                array[i] = temp;
                console.log("arrayafter", array);
            }

            return array;
        }
        //输出
        let array1 = selectionSort(array);
        for (let k = 0; k < array.length; k++) {
            console.log(array1[k]);
        }

4.快速排序

选一个数(一般选第一个),作为标杆,将比它小的数存在它的左边,比它打的数存在右边,再分别左右进行第二次排序,直至全部完成。采用递归,分治思想。
方法一:递归

 let array = [3, 9, 1, 5, 2, 3, 5, 7, 2];

        function quickSort(array) {
            //如果数组长度为1,直接返回
            if (array.length <= 1) {
                return array;
            }
            //数组长度不为1
            const target = array[0];
            const left = [];
            const right = [];
            for (let i = 1; i < array.length; i++) {
                // console.log("arrayi", array[i]);
                if (array[i] < target) {
                    left.push(array[i]);
                    // console.log("left", left);
                } else {
                    right.push(array[i]);
                    // console.log("right", right);
                }
            }
            return quickSort(left).concat(target, quickSort(right));
        }
        quickSort(array);
        console.log("array", quickSort(array));

这里踩了一个坑,将left.push(array[i])写成了left.push=array[i];这会导致写不进去。
最终结果如前面结果。
方法二:
l,r分别为最左和最右。
在l<r时,右侧找到小于target的array[r],并将其赋值到array[l]
在l<r的条件下,找到左侧大于target的值array[l],并将其赋值到array[r]
这样让l=r时,左侧的值全部小于target,右侧的值全部小于target,将target放到该位置
优点是不需要额外存储空间,但写法思路较复杂

        let array = [3, 9, 1, 5, 2, 3, 5, 7, 2];


        function quickSort(array, start, end) {
            if (end - start < 1) {
                return;
            }
            const target = array[start];
            let l = start;
            let r = end;
            while (l < r) {
                while (l < r && array[r] >= target) {
                    r--;
                }
                array[l] = array[r];
                while (l < r && array[l] < target) {
                    l++;
                }
                array[r] = array[l];
            }
            array[l] = target;
            quickSort(array, start, l - 1);
            quickSort(array, l + 1, end);
            return array;
        }
        console.log("array", quickSort(array, 0, 8));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值