插入排序

直接插入排序(Straight Insertion Sort)核心思想是将是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。跟打扑克牌一样。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。

例如我们有一组数字:{5,2,4,6,1,3},我们要将这组数字从小到大进行排列。 先假设有序列表中只有第1个元素,然后从第二个数字开始,将其认为是新增加的数字,这样第二个数字只需与其左边的第一个数字比较后排好序;第三个数字时,只需与前两个数字比较即可;以此类推,直到最后一个数字与前面的所有数字比较结束,插入排序完成。

实现逻辑:

① 从第一个元素开始,该元素可以认为已经被排序。
② 取出下一个元素x(初始下标为1),在已经排序的元素序列中从后向前扫描
③ 如果元素sn(已排序)大于x,将sn元素移到下一位置
④ 重复步骤③,直到找到已排序的元素小于或者等于新元素的位置
⑤将新元素插入到该位置
⑥ 重复步骤②~⑤

代码实现:

function insertSort(arr){
    const len = arr.length;
    for(let i=1;i<len;i++){
        const temp = arr[i];
        for(j=i-1;j>=0;j--){
            if(arr[j] > temp) {
                arr[j+i] = arr[j];
            }
            else break;
        }
        arr[j+1] = temp;
    }
}

 

 上述代码存在一个缺点,新插入的元素要按顺序依次往前查找,数据量较大时,必然比较耗时。改进方法是采用二分查找法,算法思路如下:

① 从第一个元素开始,该元素可以认为已经被排序
② 取出下一个元素,在已经排序的元素序列中二分查找到第一个比它大的数的位置
③ 将新元素插入到该位置
④ 重复上述两步

function binarySearchInsertSort(arr){
    let key, left, right, middle;   
    for (let i=1; i<len; i++){   
        key = arr[i];   
        left = 0;   
        right = i - 1;   
        while (left <= right){   
            middle = ( left+ right) / 2;   
            if (arr[middle] > key)   
                right = middle - 1;   
            else   
                left = middle + 1;   
        }   
        //比key值大的需要依次往后挪一个位置,这样才能为key插入的下标位置腾出空间
        for(let j= i - 1; j >= left; j--){   
            arr[j+1] = arr[j];   
        }   
        arr[left] = key;          
    } 
}

 

posted @ 2022-04-20 22:44  我是格鲁特  阅读(46)  评论(0编辑  收藏  举报