《算法之选择排序》

141 阅读2分钟

思想:

对数组循环,第一次循环,找到所有元素中的最小值,把它和下标为0的元素交换,这样,i=0位置的元素就是所有元素的最小值。

第二次循环,令i=1,因为此时i=0位置已经定死了,所以,找剩余所有元素的最小值,也就是从i=1往后的元素,找到最小值后,和i=1位置的元素交换,这样,i=1位置的元素就是第二小的。

以此类推,即,每次循环,目的是找到从i往后的剩余元素的最小值,然后把这个最小值放到当前i的位置。

细节:

  • 找到最小值并且交换时,可以使用if...else,判断,如果我找到的最小值的下标和i不一样时,才交换,如果一样(i就是最小值)那就什么都不做,直接进入下一次循环。
  • i循环的范围,i取到倒数第二个下标就可以。因为,把倒数第二个位置的值定好,那最后一个位置的就自动定好了。
  • 每一次进入新的循环时,由于前边的位置都定好了,所以,在找最小值时,要排除前边那些值,直接从i往后的数组元素中找。
  • 可以使用两个子函数,swap()交换两个下标处的元素。minIndex()返回数组中最小值的下标。
let swap=(array,i,j) =>{
    let temp=array[i]
    array[i]=array[j]
    array[j]=temp
}    //数组做形参,在传实参时是复制数组的地址,在函数中做的操作也会改变实参。
let minIndex=numbers =>{
    let minindex=0
    for(let i=1;i<numbers.length;i++){
        if (numbers[i]<numbers[minindex]){
            minindex=i
        }
    }
    return minindex
}
let sort=numbers =>{
    for (let i=0;i<numbers.length-1;i++){
        let min_index=minIndex(numbers.slice(i))+i
        if (i!==min_index){
            swap(numbers,i,min_index)
        }
    }
    return numbers
}

下边是不用子函数的代码:

let sort=numbers =>{
    for(let i=0;i<numbers.length-1;i++){
        temp=numbers.slice(i)
        let min=0
        for(let j=1;j<temp.length;j++){
            if (temp[j]<temp[min]){
                min=j
            }
        }
        min=min+i  //找到从i往后所有元素的最小值的下标min
        if(i!==min){
            temp2=numbers[i]
            numbers[i]=numbers[min]
            numbers[min]=temp2
        }         //如果min和当前等着被放元素的位置i不一样,就交换
    }
    return numbers
}

以前学排序算法的时候总是很懵,可能是因为没有写子函数的原因吧。。。所以写的乱七八糟的。用了两个子函数之后,代码就很清晰易懂了。

每次循环就做两件事情:

  1. 找到从i往后元素的最小值的下标,记为min

  2. 交换min和i处的元素

第一步就可以抽象出一个函数,找任意长度的数组中的最小值下标。

时间复杂度:n*n