排序算法

折半插入算法、直接插入算法、希尔排序算法如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp4
{
    class Program
    {
        static void Main(string[] args)
        {
            {
                //直接插入排序
                int[] arr = { 23, 22, 12, 30, 10 };
                Console.WriteLine("待排序的数组为: ");
                PrintArr(arr);
                SortDirect(arr);
                Console.WriteLine("直接插入排序后的数组为: ");
                PrintArr(arr);
            }
            {
                //折半插入排序
                int[] arr = { 8,18,20,33,39,21 };
                Console.WriteLine("待排序的数组为: ");
                PrintArr(arr);
                HalfSort(arr);
                Console.WriteLine("折半插入排序后的数组为: ");
                PrintArr(arr);
            }
            {
                //希尔排序
                
                int[] arr = { 8, 18, 20, 33, 39, 21, 2, 43, 100 };
                Console.WriteLine("待排序的数组为: ");
                PrintArr(arr);
                ShellSort(arr);
                Console.WriteLine("折半插入排序后的数组为: ");
                PrintArr(arr);
            }
            Console.Read();
        }

        private static void PrintArr(int[] arr)
        {
            foreach (var item in arr)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine();
        }


        /// <summary>
        /// 直接插入排序
        /// </summary>
        /// <param name="arr">待排序数组</param>
        static void SortDirect(int[] arr)
        {

            /*
              待排序数组{23, 22, 12, 30, 10 }          从小到大排序
              第一轮排序  22 23 12, 30, 10             22 和 23比较     
              第二轮排序  12  22  23  30  10           12   和  23 比较   换位->    12  和   22 比较  换位
              第三轮排序   12  22  23  30  10          30  和  23 比较     
              第四轮排序   10  12  22  23  30          10 和  30 比较 换位   ->   10  和 23  比较  换位->  10 和22  比较 换位  ->  10 和 12 比较  换位

            */
            for (int i = 1; i < arr.Length; i++)
            {     //假设已经到了第二轮排序  待排 22 23 12, 30, 10          i = 2   
                var curValue = arr[i];         //curValue = 12
                var temp = i;         //temp = 2
                while(temp > 0 &&(arr[temp-1] > curValue)) //1.arr[temp-1] = 23  > curValue=12   2.    arr[temp-1] = 22   > curValue = 12
                {
                    arr[temp] = arr[temp-1];        //1.  第三位变成23     2.   第二位变成  22
                    temp--;                           //1.temp = 1        2.  temp = 0
                }
                arr[temp] = curValue;      //最小的始终放到最前边
            }
        }

        /// <summary>
        /// 折半插入排序
        /// </summary>
        /// <param name="arr">{8,18,20,33,39,21}</param>
        static void HalfSort(int[] arr)
        {
            int len = arr.Length;              //数组长度6
            int insertValue = arr[len- 1];     //待插入数据为21

            int low = 0;
            int high = len - 2;     //4
            while (low <= high)
            {
                int middle = (low + high) / 2;          //2
                if(insertValue < arr[middle])          //1.  21< 20  false     2. 21 < 33 true
                {
                    high = middle - 1;                 //2. high =2
                }
                else                
                {
                    low = middle + 1;                 //1.low = 3   high=4    2. low=3  high=2
                }
            }
            for (int j = len -1; j > high+1; j--)       //1.j = 5  j  > 3  j--
            {
                arr[j] = arr[j - 1];               //待插入位置后数据后移 
            }
            arr[high + 1] = insertValue;
        }

        /// <summary>
        /// 希尔排序
        /// </summary>
        /// <param name="arr">待排序数组</param>
        static void ShellSort(int[] arr)
        {

            int len = arr.Length;       //len=9  
            int temp = 0;
            for (int k = len/2; k > 0; k = k/2)      
            {
                Console.WriteLine($"外层循环k={k}
");
                for (int i = k; i < len; i++)
                {
                    Console.WriteLine($"--内层循环--i={i}");
                    Console.WriteLine($"准备交换的数据为: {arr[i - k]}--{arr[i]}");
                    if (arr[i-k] > arr[i])
                    {
                        Console.WriteLine($"####需要交换的数据为: {arr[i-k]}<-->{arr[i]}" );
                        temp = arr[i - k];
                        arr[i - k] = arr[i];
                        arr[i] = temp;
                    }
                    
                }
                Console.Write("外层循环k={k}排序结果:  ");
                foreach (var item in arr)
                {
                    Console.Write(item + " ");
                }
                Console.WriteLine();

                #region 打印过程
                /*
  准备数组{ 8, 18, 20, 33, 39, 21, 2, 43, 100 }
外层循环k=4

--内层循环--i=4
准备交换的数据为: 8--39
--内层循环--i=5
准备交换的数据为: 18--21
--内层循环--i=6
准备交换的数据为: 20--2
####需要交换的数据为: 20<-->2
--内层循环--i=7
准备交换的数据为: 33--43
--内层循环--i=8
准备交换的数据为: 39--100
外层循环k={k}排序结果:  8 18 2 33 39 21 20 43 100
外层循环k=2

--内层循环--i=2
准备交换的数据为: 8--2
####需要交换的数据为: 8<-->2
--内层循环--i=3
准备交换的数据为: 18--33
--内层循环--i=4
准备交换的数据为: 8--39
--内层循环--i=5
准备交换的数据为: 33--21
####需要交换的数据为: 33<-->21
--内层循环--i=6
准备交换的数据为: 39--20
####需要交换的数据为: 39<-->20
--内层循环--i=7
准备交换的数据为: 33--43
--内层循环--i=8
准备交换的数据为: 39--100
外层循环k={k}排序结果:  2 18 8 21 20 33 39 43 100
外层循环k=1

--内层循环--i=1
准备交换的数据为: 2--18
--内层循环--i=2
准备交换的数据为: 18--8
####需要交换的数据为: 18<-->8
--内层循环--i=3
准备交换的数据为: 18--21
--内层循环--i=4
准备交换的数据为: 21--20
####需要交换的数据为: 21<-->20
--内层循环--i=5
准备交换的数据为: 21--33
--内层循环--i=6
准备交换的数据为: 33--39
--内层循环--i=7
准备交换的数据为: 39--43
--内层循环--i=8
准备交换的数据为: 43--100
外层循环k={k}排序结果:  2 8 18 20 21 33 39 43 100
                */
                #endregion
            }
        }
    }
}
原文地址:https://www.cnblogs.com/morec/p/12058841.html