博客园不常在线

有问题联系微信

微信号

微信公众号

C#数据结构与算法系列(二十一):希尔排序算法(ShellSort)

1.介绍

希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。

2.基本思想

希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止

3.示意图

 

 4.代码

using System;

namespace DataStructure
{
    public class ShellSort
    {
        /// <summary>
        /// 测试希尔排序
        /// </summary>
        public static void Test()
        {
            int[] arr = { 8, 9, 1, 7, 2, 3, 5, 4, 6, 0 };

            Console.WriteLine("需要排序的数组:" + ArrayToString(arr));

            Console.WriteLine("\n封装后的测试");

            //测试封装后的希尔排序
            Sort(arr);

            Console.WriteLine("\n封装前的测试");


            arr = new int[] { 8, 9, 1, 7, 2, 3, 5, 4, 6, 0 };

            int temp = 0;
            //希尔排序第一轮
            //因为第一轮排序,是将十个数据分成了五组
            for (int i = 5; i < arr.Length; i++)
            {
                //遍历各组中所有元素(10/2=5)步长五
                for (int j = i - 5; j >= 0; j -= 5)
                {
                    if (arr[j] > arr[j + 5])
                    {
                        temp = arr[j];

                        arr[j] = arr[j + 5];

                        arr[j + 5] = temp;
                    }
                }
            }

            Console.WriteLine("\n第一轮希尔排序的结果:" + ArrayToString(arr)); //3,5,1,6,0,8,9,4,7,2

            //希尔排序第二轮
            //因为第二轮排序,是将十个数据分成了5/2=2组
            for (int i = 2; i < arr.Length; i++)
            {
                for (int j = i - 2; j >= 0; j -= 2)
                {
                    if (arr[j] > arr[j + 2])
                    {
                        temp = arr[j];

                        arr[j] = arr[j + 2];

                        arr[j + 2] = temp;
                    }
                }
            }

            Console.WriteLine("\n第二轮希尔排序的结果:" + ArrayToString(arr));

            //希尔排序第三轮
            //因为第三轮排序,是将十个数据分成了2/2=1组
            for (int i = 1; i < arr.Length; i++)
            {
                for (int j = i - 1; j >= 0; j -= 1)
                {
                    if (arr[j] > arr[j + 1])
                    {
                        temp = arr[j];

                        arr[j] = arr[j + 1];

                        arr[j + 1] = temp;
                    }
                }
            }

            Console.WriteLine("\n第三轮希尔排序的结果:" + ArrayToString(arr));
        }

        /// <summary>
        /// 封装希尔排序
        /// </summary>
        /// <param name="arr"></param>
        private static void Sort(int[] arr)
        {
            int temp = 0;

            int count = 0;
            //遍历各组中的所有元素(共gap组,每组有个元素),步长gap
            for (int gap = arr.Length / 2; gap > 0; gap /= 2)
            {
                for (int i = gap; i < arr.Length; i++)
                {
                    for (int j = i - gap; j >= 0; j -= gap)
                    {
                        //如果当前元素大于加上步长后的那个元素,说明交换
                        if (arr[j] > arr[j + gap])
                        {
                            temp = arr[j];

                            arr[j] = arr[j + gap];

                            arr[j + gap] = temp;
                        }
                    }
                }

                Console.WriteLine($"\n第{++count }轮希尔排序的结果:{ArrayToString(arr)}");
            }
        }

        private static string ArrayToString(int[] arr)
        {
            return string.Join(",", arr);
        }
    }
}

5.演示结果

 

posted @ 2020-07-04 14:37  Code技术分享  阅读(300)  评论(0编辑  收藏  举报