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

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

原理
直接插入排序是挨个的去比较,而二分插入排序则是利用二分搜索的原理,将待排序的元素与左侧已经排好序的队列的中间元素(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)
    }

}

运行结果

原文地址:http://blog.51cto.com/13022101/2150214

时间: 2024-11-06 09:35:54

[golang] 数据结构-二分插入排序的相关文章

[golang] 数据结构-直接插入排序

原理直接插入排序,也是一种非常简单的排序算法.第一轮先从第二个元素开始,和第一个比较,如果较小就交换位置,本轮结束.第二轮从第三个元素开始,先与第二个比较,如果较小就与第二个交换,交换后再于第一个比较.如此循环直至最后一个元素完成比较逻辑. 复杂度最好的情况下,直接插入排序只需进行n-1次比较,0次的交换.平均下来时间复杂度为 O(n^2).由于是每个元素逐个与有序的队列进行比较,所以不会出现相同数值的元素在排序完成后交换位置.所以直接插入排序是种稳定的排序算法. 代码 package main

golang数据结构之插入排序

//InsertSort 插入排序 func InsertSort(arr *[7]int) { for i := 1; i < len(arr); i++ { insertVal := (*arr)[i] inserIndex := i - 1 for inserIndex >= 0 && (*arr)[inserIndex] > insertVal { (*arr)[inserIndex+1] = (*arr)[inserIndex] inserIndex-- } /

【数据结构与算法 00】二分插入排序

算法思想(从小到大排序) N1:遍历数组 array[10000], i 为数组坐标,从1开始 N2:以 i 为基数 tmpV=array[i],[0 ,i-1] 为区间坐标,(0+i-1)/2 为 mid 坐标 N3:比较 tmpV 与 array[mid],如果大于,则区间为 [mid+1,i-1],否则为[0,mid-1] N4:遍历所有 i 实现以上递归步骤,直到 右坐标<左坐标,因为 while 递归判断时:right>left 区间还有n个数,正常递归,当right=left=mi

直接插入排序与二分插入排序的C++实现

1.直接插入排序 直接插入排序的过程可以理解为一个固定长度的数组被分为两个集合,即已排序集合和未排序. 开始时已排序集合为空,而未排序集合即为整个数组.当排序开始后插入一个对象,已排序集合元素数目加1,相应地未排序集合元素数目减1,重复插入过程直至将未排序集合清空为止,这时排序集合就是最终结果.如下图: C++实现如下,为了使得程序可以对各种基本数据类型都能排序,使用了模板类,注意模板类的类声明和成员函数实现必须在同一个cpp文件里面,不能分开!! 1 #ifndef INSERTSORT_H

二分插入排序JAVA实现

package kpp.sort; /** * 当前待插入元素data[i],若data[i]>=data[i-1],则表示排序正常,i++处理下一个元素 * 若data[i]<data[i-1],先保存data[i]至temp,二分查找到适合插入的位置k,从k到i-1的元素顺序右移 * 将temp插入到k * * 分析: * 二分插入排序的比较次数与待排序记录的初始状态无关,仅依赖于记录的个数. * 当n较大时,比直接插入排序的最大比较次数少得多.但大于直接插入排序的最小比较次数. * 算法

二分插入排序

二分插入排序算法 一.基本思想:源自于二分查找,假设表中元素是按升序排列,将待插入的关键字与表中间位置记录的关键字与作比较.如果小于该关键字,则将元素插入后面的子表中,反之,如果大于该关键字,则将元素插入前面的子表中.反复迭代,直至所有关键字全部插入表中. 二.C 语言代码: 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 //对 R[0...n-1] 递增有序进行直接插入排序 5 void binaryInsertSort(RecTy

常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)

一下是一些常见的排序算法: 交换元素(后面算法都有用到): // 交换元素 private static void swap(int[] a, int i, int j) { int temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } 冒泡排序(有优化): // 冒泡排序(优化①,②,③,④) private static void bubbleSort(int[] a) { boolean flag = false;// ①表示整个序列是无序的 for

快速排序/二分插入排序的swift以及Java实现

经常会用到排序的算法,比如:冒泡法,选择法,快速排序,二分插入排序等等.前面两个就不说了,贴出来自己写的快速排序和二分插入排序的Swift及Java的代码实现,喜欢的话control+C拿去用. swift实现快速排序和二分插入排序算法: (想运行的话,直接复制代码,替换掉控制器里的viewDidLoad方法就好了) override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading

Python使用二分插入排序竟然比直接插入排序快99倍!

?? Python使用二分插入排序竟然比直接插入排序快99倍! 之前发布同一个算法,C++竟然比C快8倍! , 有同学提出是因为C++中使用了二分插入排序,于是用python比较了下两种排序差距有多大. 测试结果如下: Python insertion sort took time: 1:39:42.448904Python insertion sort with binary search took time: 0:01:13.263267 代码如下: import datetime impo