算法总结(一)初级排序算法

本文介绍了三种初级排序算法:选择排序通过交换找到最小元素的位置来排序;插入排序通过逐步将元素插入已排序部分来排序,效率受初始顺序影响;希尔排序则改进了插入排序,通过不同间隔的元素交换实现快速排序。希尔排序通过逐步减小间隔,最终完成排序。
摘要由CSDN通过智能技术生成

选择排序

首先找到数组中最小的数,将他与第一个元素交换位置,依此类推

var arr = []
for (let i = 0; i < 10000; i++) {
    arr.push(parseInt(Math.random() * 10000))
}
console.log(arr)
// 排序算法
let arr2 = JSON.parse(JSON.stringify(arr))
let num = 0
for (let i = 0; i < arr2.length; i++) {
    for (let j = 0; j < arr2.length - 1 - i; j++) {
        num++
        if (arr2[j] > arr2[j + 1]) {
            let a = arr2[j]
            arr2[j] = arr2[j + 1]
            arr2[j + 1] = a
        }
    }
    console.log(arr2)
    console.log('_______________________')

}
console.log('选择排序', num, arr2)

插入排序

        通常情况下,人们整理桥牌的方法是一张一张的来,将每一张牌插入到其他已经有序的牌中的适当位置。在计算机的实现中,为了给要插入的元素腾出空间,我们需要将其余所有元素在插入之前都向右移动一位。这种算法叫插入排序。
        与选择排序一样,当前索引左边的所有元素都是有序的,但他们的最终位置还不能确定,为了给更小的元素腾出空间,他们可能会被移动。但是当索引到达数组的右端时,数组排序就完成了。
        和选择排序不同,插入排序所需的时间取决于输入中元素的初始顺序。例如:对一个很大且其中的元素已经有序(或者接近有序)的数组进行排序将会比对随机顺序的数组或是逆序数组进行排序要快的多。

var arr = []
for (let i = 0; i < 10000; i++) {
    arr.push(parseInt(Math.random() * 10000))
}
let arr3 = JSON.parse(JSON.stringify(arr))
let num2 = 0
for (let i = 2; i < arr3.length; i++) {
    if (arr3[i] < arr3[i - 1]) {

        arr3.some((item, index) => {
            num2++
            if (arr3[i] < item) {
                let a = arr3[i]
                arr3.splice(i, 1)
                arr3.splice(index, 0, a)
                return true
            }
        })
    }
    // console.log(arr3)
    // console.log('_______________________')

}
console.log('插入排序', num2, arr3)

希尔排序

        为了展示初级算法性质的价值,接下来我们将学习一种基于插入排序的快速的排序算法。对于大规模乱序数组插入排序很慢,因为他只会交换相邻的元素,因此元素只能一点一点的从数组的一端移动到另一端。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确位置就需要N-1次移动。希尔排序为了加快速度简单的改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。
        希尔排序的思想是使数组中任意间隔为h的元素都是有序的。这样的数组被称为h有序数组。换一句话说,一个h有序数组就是h哥互相独立的有序数组编织在一起组成的一个数组。在进行排序时,如果h很大,我们就能将元素移动到很远的地方,为实现更小的h有序创造方便,用这种方式,对于任意以1结尾的h序列,我们都能够将数组排序。这就是希尔排序。
        实现希尔排序的一种方法是对于每个h,用插入排序将h个子数组独立的排序。但因为子数组是相互独立的,一个更简单的方法是在h-子数组中将每个元素交换到比它大的元素之前去(将比他大的元素向右移动一格)。只需要在插入排序的代码中将移动元素的距离由1改为h即可。这样,希尔排序的实现就转化为了一个类似于插入排序但使用不同增量的过程。

var arr = []
for (let i = 0; i < 100; i++) {
    arr.push(parseInt(Math.random() * 100))
}
// 希尔排序
let arr4 = JSON.parse(JSON.stringify(arr))
let num4 = 0
let h = 10
function shellSort (array, h = 10) {
    let gap = Math.floor(array.length / h)
    
    while (1 <= gap) {
        // 把距离为 gap 的元素编为一个组,扫描所有组
        for (let i = gap; i < array.length; i++) {
            let j = 0;
            let temp = array[i]
            // 对距离为 gap 的元素组进行排序,一直循环,直到当前数移到最小得地方
            for (j = i - gap; j >= 0 && temp < array[j]; j -= gap) {
                num4++
                array[j + gap] = array[j]
            }
            num4++
            array[j + gap] = temp
        }
        gap = Math.floor(gap / 2)
    }
    return array
}
console.log('希尔排序', shellSort(arr4), num4)

算法结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值