插入排序及时间复杂度分析

温故一下插入排序,下面是代码:

package com.chanspace.arraysort;

import java.util.Arrays;

/**
 * 类名称:InsertSort
* 类描述:
* 创建时间:2018年07月18日
* * @author jiangcheng * @version 1.0.0 */ public class InsertSort { public static void main(String[] args) { int[] arr = {32,43,23,13,5}; System.out.println("before sort , arr :" + Arrays.toString(arr)); insertSort(arr); System.out.println("after sort , arr :" + Arrays.toString(arr)); } public static void insertSort(int[] arr){ int length = arr.length; for (int i = 1; i < length; i++) {//这里的i是被插入的值的位置,也就是从第二个开始,最后一个结尾 i -> [1,length) int v = arr[i];//使用v暂存arr[i],v代表被插入的值 int j = i-1; //int b = arr[i-1];//使用 b 暂存i前面的数 //无意义 /*if (v < b) { //如果v比b小则交换位置 arr[i] = arr[i-1]; arr[i-1] = v; }*/ //arr[i] = b; //无意义 //因为 v 每次跟 前面的数比较之后 位置 往前推一位 之后还要继续跟之前的数进行比较 不断往前推 while (j >= 0 && v < arr[j]) { // j >= 0 有必要限制循环次数 也要注意这里 包括了 j = 0 的情况 //v 是被比较的数 , j是比大小的数 , j 从 i-1 开始,符合条件就 往前推 //------------------------- //arr[j] = arr[j-1]; arr[j+1] = arr[j]; //替换后面的比替换前面的好 //第一次相当于 i 和 j调换了 //arr[j-1] = v; //这里赋值没有意义 后面就会被 重新赋值了 //------------------------- j--; } //当推进到 v 大于 arr[j] 的 时候 就可以 知道 v 应该 放在 arr[j] 的后面 因 j-- 已经操作 所以 当前的 arr[j] 还是原始值 而arr[j + 1]已经不是原始值了 arr[j+1] = v; } } }

复杂度分析: 

代码               时间代价   执行次数

int v                       c1      1次

int i=1;i=0 && arr[j] > v)   c5       这里我们无法判断具体的执行次数,但是知道外层循环要执行n-1次,假设第i次循环中这里执行k(i)次,那么共执行k(1)+k(2)+...+k(n-1)次

arr[j+1] = arr[j]       c6     循环内的语句总比循环数少1,于是共执行(k(1)-1)+(k(2)-1)+...+(k(n-1)-1)次

j--;              c7     同理,共执行(k(1)-1)+(k(2)-1)+...+(k(n-1)-1)次

arr[j+1] = v           c8      n-1次

当规模为n时

                 最好情况         最差情况

比较次数           n-1            2+3+4+……+n=(n+2)n/2

移动次数            0             1+2+3+……+n-1=n*n/2

若待排序对象序列中出现各种可能排列的概率相同,则可取上述最好情况和最坏情况的平均情况。

在平均情况下的关键字比较次数和对象移动次数约为 n^2/4。因此,直接插入排序的时间复杂度为 o(n^2)。

你可能感兴趣的:(算法与数据结构)