c# 插入排序,希尔排序


插入排序:

假设待排序集合是桌上的牌,每次抽一张,

手里的牌是有序的,将抽到的牌,插入手中合适的位置,

保证手中的牌一直是有序的..

具体的是两层循环:

  外层循环每次抽一张牌

  内层循环是将抽到的牌,从后往前与手中的牌(已排序部分)比较,如果手中的牌大,

则将已经手中的牌后移,反之,就将抽到的牌插入它的后边.进入下一轮外循环.

 1 public static void Insertion_Sort(int[] source)
 2         {
 3             int length = source.Count();
 4             for (int p = 1; p < length; p++)
 5             {
 6                 var temp = source[p];
 7                 int realIndex = 0;
 8                 for (int i = p-1; i >=0; i--)
 9                 {
10                     if (source[i] > temp)//往后移动一位
11                     {
12                         source[i + 1] = source[i];
13                         realIndex = i;
14                     }
15                     else
16                     {
17                         realIndex = i + 1;
18                         break;
19                     }                   
20                 }
21                 source[realIndex] = temp;
22             }
23         }

希尔排序

是插入排序的优化

首先需要定义一组增量序列,保证起始值为1,结束值小于数组元素个数,比如

用2k-1这个公式去生成(Hibbard)

        public static List<int> HibbardList(int length)
        {
            List<int> range = new List<int>();
            for (int i = 1; Math.Pow(2,i)-1 < length; i++)
            {
                range.Add((int)Math.Pow(2, i) - 1);
            }
            return range;
        }

整体排序需要三层循环,最外层循环是对上述互质序列循环,执行完一轮保证间隔互质序列中的一个数字,是有序的;

就像是,抽一轮牌,保证手中的牌是间隔某个数有序的,然后再把牌放到桌上(不要洗牌!!!),再抽一次,保证一个更小的间隔有序,直至这个间隔是1;

为什么间隔数序列最好两两互质.

下两层循环逻辑和插入排序一样.

 1  public static void Shell_Sort(int[] source,List<int> range)
 2         {
 3             for (int d =range.Count-1 ; d >=0; d--)
 4             {
 5                 //间隔dd进行插入排序
 6                 int dd = range[d];
 7                 for (int p = dd; p < source.Length; p++)//注意p的增量是1,而不是dd
 8                 {
 9                     var temp = source[p];
10                     int realIndex = 0;
11                     for (int i = p - dd; i >= 0; i-=dd)
12                     {
13                         if (source[i] > temp)
14                         {
15                             source[i + dd] = source[i];
16                             realIndex = i;
17                         }
18                         else
19                         {
20                             realIndex = i + dd;
21                             break;
22                         }
23                     }
24                     source[realIndex] = temp;                   
25                 }
26             }
27         }
28  public static void ShellHibbard_Sort(int[] nums)
29         {
30             Shell_Sort(nums, HibbardList(nums.Length));
31         }

核心思想来自B站:<浙江大学数据结构>(c语言),何老师,陈老师逻辑清晰,语言简洁.我这种非计算机专业的也听起来也感觉很棒!

因为我的学习目标是用c#做建筑软件二次开发,主要是不会c语言:(,故将思想用c#实践.程序测试没问题.