插入排序之直接插入排序
根据寻找插入位置方法分直接插入排序、折半插入排序、希尔插入排序。这里只提直接插入排序。
理论可参考:排序算法一:直接插入排序
插入排序的基本思想是:每次将一个待排序的记录(如数组、链表)分为两部分,前半部分是已经排序的,后半部分是未排序的。在排序时只需要在未排序的部分中选择一个元素按其大小插入到已经排好序的子序列中的适当位置,直到全部记录插入完成为止。初始时,可假设已排序部分就是第一个元素。
简单的来说,就是每一步都将一个待排数据按其大小插入到已经排序的数据中的适当位置,直到全部插入完毕。
下图演示了对4个元素进行直接插入排序的升序过程,共需要(a),(b),(c)三次插入。
java代码实现:
public static void insertSort(int[] arr) { int length = arr.length; for (int i = 1; i < length; i++) { int j = i; int waitInsert = arr[i]; while(j > 0 && arr[j - 1] > waitInsert){ arr[j] = arr[j - 1]; j--; } arr[j] = waitInsert; } }
在上边脚本基础上,增加了一个判断,时间复杂度变低。
static void insertSort(int[] arr) { for (int i = 1; i < arr.Length; i++) { if (arr[i - 1] > arr[i]) { int waitInsert = arr[i];
int j = i; while (j > 0 && arr[j - 1] > waitInsert)
{ arr[j] = arr[j - 1]; j--; } arr[j] = waitInsert;
} } } static void Main(string[] args) { int[] x = { 6, 2, 4, 1, 5, 9 }; insertsort(x); foreach (var item in x) { if (item > 0) Console.WriteLine(item + ","); } Console.ReadLine(); }
python实现
def insert_sort(alist): # 从第二个位置,即下标为1的元素开始向前插入 for i in range(1, len(alist)): # 从第i个元素开始向前比较,如果小于前一个元素,交换位置 for j in range(i, 0, -1): if alist[j] < alist[j-1]: alist[j], alist[j-1] = alist[j-1], alist[j] alist = [54,26,93,17,77,31,44,55,20] insert_sort(alist) print(alist)
时间复杂度
- 最优时间复杂度:O(n) (升序排列,序列已经处于升序状态)
- 最坏时间复杂度:O(n2)
- 稳定性:稳定
参考资料:
1、经典排序算法 – 插入排序Insertion sort (java实现)
2、排序算法一:直接插入排序 (C++实现)