JavaScript——数组的应用内排序

目录

任务描述

相关知识

冒泡排序

一趟冒泡排序

冒泡排序全过程

选择排序

一趟选择排序

选择排序全过程

编程要求

任务描述

本关任务:掌握冒泡排序和选择排序。

相关知识

所谓排序是指将一组数据按照从小到大(或从大到小)的顺序重新排列,排序是面试常考的问题之一。

排序一般分为两个步骤:比较和移动。比较指判断两个数据之间的大小关系,移动指根据大小关系把数据移动到合适的位置上。

待排序的数据大多是放置在数组中,一是因为数组中的数据有相对的顺序,二是遍历数组操作起来比较简单。

下面介绍 JavaScript 中两种常见的排序方式:冒泡排序和选择排序。

冒泡排序

一趟冒泡排序

先介绍一趟冒泡排序的过程。

以升序为例,从第一个元素开始,将第一个元素与第二个元素比较,如果第一个元素大于第二个元素,交换这两者。

如图1所示,9比5大,交换两者的位置后,9就到后面去了。

图1

然后第二个元素与第三个元素比较,将大的移动到后面;第三个元素与第四个元素比较......,这样一直进行下去,直到倒数第二个元素和最后一个元素进行比较,称为一趟冒泡排序,结束后最大的元素已经移到了索引最大处。图2展示了每一次比较并交换后的数组:

图2

可以看到,一趟冒泡排序结束后,最大的元素`9`移到了索引最大处。

冒泡排序全过程

接下来对除了最后一个元素的数组进行第二趟冒泡排序,结果是第二大的元素到了索引第二大的地方。这样一直进行下去,直到整个数组有序或者某一趟排序的时候不存在元素的交换。如图3

图3

第四趟冒泡过程中,未发生元素的交换,结束。

因为排序的原理是不断的把大的数据往上浮动,故而命名为冒泡排序。

// 冒牌排序
var arr = [9,5,8,0,2,6];
var aLength = arr.length;
var temp;
var flag = 0;    // 元素交换的标志位
for(var i = 1;i < aLength;i++) {    // 共进行n-1次冒泡
    flag = 0;
    for(var j = 0;j < aLength-i;j++) {    // 一次冒泡
        if(arr[j]>arr[j+1]) {    // 交换元素
            temp = arr[j];
            arr[j] = arr[j+1];
            arr[j+1] = temp;
            flag = 1;
        }
    }
    if(flag == 0) break;    //    本次冒泡没有元素交换
}
console.log(arr);

冒泡排序关键在于这两个循环的控制,外层循环控制冒泡的次数,一般是n-1次,n表示数组长度。

内循环j的初值为0,因为不论是第几趟冒泡,都是从arr[0]开始遍历数组,j的上限设置为arr.length-i,因为随着冒泡的进行,越往后需要比较的数组的索引上限越小。

选择排序

一趟选择排序

原理:遍历数组,记录下最大元素的索引值,将最大的元素与数组最后一个元素交换,这样最大的元素到了索引值最大的地方,称为一趟选择排序。与冒泡不同的是,只会发生一次交换。如图4

图4

可以看到9移到了索引最大处。

选择排序全过程

第二趟选择排序是在除了最后一个元素的数组中选择最大的元素,将它与索引值第二大的元素交换,结束后第二大的元素也到了最终的位置上。这样一直进行下去,一共n-1趟选择排序。如图5

图5

// 选择排序
var arr = [6,12,3,34,1,56,77,0,2,43];
var aLength = arr.length;
var temp;
var max = arr[0];
var maxIndex = 0;
for(var i = 0;i < aLength-1;i++) {    // 共进行n-1次选择
    for(var j = 1;j < aLength-i;j++) {    // 一次选择
        if(arr[j] > max) {
            max = arr[j];
            maxIndex = j;
        }
    }
    // 将本次选出的最大元素移动到最终的位置上
    temp = arr[aLength-i-1];
    arr[aLength-i-1] = arr[maxIndex];
    arr[maxIndex] = temp;
    var max = arr[0];
    var maxIndex = 0;
}
console.log(arr);

这里也有两个大循环,第一个循环控制总的排序趟数,第二个循环求本次选择出的最大元素的索引值,第二个循环结束后将本次的最大值与最终位置上的元素交换。

编程要求

本关的编程任务是补全右侧代码片段中 Begin 至 End 中间的代码,具体要求如下:

  • 函数mainJs(a)中的变量arr是一个数组,你需要对该数组进行选择排序;

  • 返回选择排序进行过程中,在每一趟交换前,待排序子数组的最大元素的位置组成的数组;

  • 比如对于上面相关知识中的数组[9,5,8,0,2,6],第一次交换前,最大的元素9的索引是0,第二次交换前,最大元素8的索引是2,第三次交换前最大元素6的索引是0,第四次交换前最大元素5的索引是1,第五次交换前最大元素2的索引是1,第六次交换前最大元素0的索引是0。索引需要返回的数组是[0,2,0,1,1,0]

    function mainJs(a) {
        var arr = a.split(",");
        for(var i = 0;i < arr.length;i++) {
            arr[i] = parseInt(arr[i]);
        }
        //请在此处编写代码
        /*********begin*********/
        var length = arr.length;
        var max = arr[0];
        var t = 0;
        var maxindex = 0;
        var newArr = new Array();
        for (var i = 0; i < length - 1; i++){
            for (var j = 1; j < length - i; j++){
                if (arr[j] > max) {
                    max = arr[j];
                    maxindex = j;
                }
            }
            newArr.push(maxindex);
            t = arr[length - i - 1];
            arr[length - i - 1] = arr[maxindex];
            arr[maxindex] = t;
            var max = arr[0];
            var maxindex = 0;
        }
        return newArr;
        /*********end*********/
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值