为了账号安全,请及时绑定邮箱和手机立即绑定

[golang] 数据结构-二分插入排序

标签:
Go


接上文 直接插入排序

直接插入排序每轮比较中,都需要把待处理的元素与前面每一位元素进行比较。那么有没有一种方法可以优化下,减少比较次数呢?答案当然是有的,下面介绍的二分插入就是直接插入排序的优化算法之一。

原理

直接插入排序是挨个的去比较,而二分插入排序则是利用二分搜索的原理,将待排序的元素与左侧已经排好序的队列的中间元素(n/2)进行比较。较小时则继续与中间元素左侧队列中间元素进行比较,较大则与中间元素右侧队列的中间元素进行比较,直至找到合适的位置,再讲这个位置后续的元素向后移动一位,带插入的元素放到这个合适的位置,从而完成一轮排序。

复杂度

平均时间复杂度为O(n^2),空间复杂度始终为1。最佳情况时,仅需进行n-1次比较,无需交换。

因为不会相同数值元素的先后顺序,所以它也是一种稳定排序。

代码实现

package main

import (

    "fmt"

    "math/rand"

    "time"

)

func main() {

    var length = 10

    var list []int

    // 以时间戳为种子生成随机数,保证每次运行数据不重复

    r := rand.New(rand.NewSource(time.Now().UnixNano()))

    for i := 0; i < length; i++ {

        list = append(list, int(r.Intn(1000)))

    }

    fmt.Println(list)

    for i := 1; i < length; i++ {

        // 利用二分查找,在待排元素左侧找到合适的插入位置

        p := suitableIndex(list, 0, i-1, i)

        // 如果最合适的位置不是待排元素当前位置,那就一次把合适位置后的元素都向后移动一位

        if p != i {

            temp := list[i]

            for j := i; j > p; j-- {

                list[j], list[j-1] = list[j-1], list[j]

            }

            list[p] = temp

        }

        fmt.Println(list)

    }

}

func suitableIndex(list []int, start int, end int, current int) int {

    // 比到最后美的比的时候就去对比下当前位置与待排元素的大小,并返回较大值的位置

    if start >= end {

        if list[start] < list[current] {

            return current

        } else {

            return start

        }

    }

    center := (end-start)/2 + start

    // 如果中间的元素比较大,就继续向左侧寻找。反之则向右

    if list[center] > list[current] {

        return suitableIndex(list, start, center, current)

    } else {

        return suitableIndex(list, center+1, end, current)

    }

}

运行结果

[golang] 数据结构-二分插入排序

©著作权归作者所有:来自51CTO博客作者NicoChen的原创作品,如需转载,请注明出处,否则将追究法律责任


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消