各种常用的插入排序(直接,折半,希尔)

来源:互联网 发布:js 浮点数相加 编辑:程序博客网 时间:2024/05/20 12:25

    本来打算昨天发,结果竟然学了一个晚上,自认为大学数据结构学得还不错,重新翻一遍竟然看了这么久还没有理解透彻,更加坚定了我一天一算法的决心。昨天和今天的排序一块写出来一块总结道插入排序里好啦。

老样子,代码走起。

<pre name="code" class="csharp">using System;/// <summary>/// 插入排序/// </summary>namespace test{class MainClass{public static void Main (string[] args){int [] arr = {3, 1, 33, 4, 6, 2, 8, 14, 5};//DirectInsertSort (arr);//BinaryInsertSort (arr);ShellSort (arr);foreach (int i in arr) {Console.WriteLine (i);}}//直接插入排序,最简单的排序,从数组第二个数开始作为关键字向前面的数字组成的数组//一次对比,并将自己插入前面数组第一个比他大的数前面,前面数组后面的数依次后移一位private static void DirectInsertSort (int [] arr) {int temp = 0;//存放作为关键字的元素的值int j = 0;for (int i = 1; i < arr.Length; i++) {//从数组第二个数开始遍历temp = arr [i];for (j = i - 1; j >= 0 && arr [j] > temp; j--) {//如果碰到一个比temp大的数,则temp索引位前比temp大的数arr [j + 1] = arr [j];//的索引位大的数依次后移一位}arr [j + 1] = temp;//由于for循环最后执行一次j--,所以将temp给j+1位的元素}}//折半插入排序,由于插入排序是对有序数列插入,前面已经排好的序列通过折半查找找到插入元素的位置private static void BinaryInsertSort (int [] arr) {for (int i = 1; i < arr.Length; i++) {int temp = arr [i];//中间变量,存放对比的关键值int low = 0;int high = i - 1;while (low <= high) {int middle = (low + high) / 2;if (temp < arr [middle]) {//若中间值大于temp说明temp的位置应该在middle后面,反之亦然high = middle - 1;} else {low = middle + 1;}}for (int j = i; j > high + 1; j--) {arr [j] = arr [j - 1];}arr [high + 1] = temp;}}//希尔排序,增量的规则一般是第一次取长度一半,第二次取一半的一半,一次递推,希尔排序不稳定//增量也可以根据实际情况写一个函数,增量是用来分割数组的,每组数字都具有增量的函数特性//好的增量序列的共同特征://1.最后一个增量必须为1//2.应该尽量避免序列中的值(尤其是相邻的值)互为倍数的情况private static void ShellSort (int [] arr) {int i, j, increment;//increment表示增量int temp = 0;increment = arr.Length / 2;//根据increment分割的各组进行直接插入排序while (increment > 0) {for (i = increment; i < arr.Length; i++) {temp = arr [i];for (j = i - increment; j >= 0 && arr [j] > temp; j -= increment) {arr [j + increment] = arr [j];}arr [j + increment] = temp;}increment = increment / 2;//每次循环increment取半,直到为1}}}}


插入排序的根本思想在于每次对有序数列进行插入值,所以前两种排序都是稳定的,时间复杂度皆为n2,而希尔排序由于多次分成多个部分进行插入排序,是不稳定的,复杂度根据增量而定,好的增量会使希尔排序的效率很高。

0 0
原创粉丝点击