第十章      实现排序算法

排序的目的是将一组“无序”的记录序列调整为“有序”的记录序列,使之按关键字递增(或递减)次序排列起来

         排序分类

  1. 按是否涉及到数据的内、外存交换分类

1)  内部排序:在排序的过程中,若整个文件都是放到内存中处理,排序时不涉及数据的内外存交换,则称之为内部排序

2)  外部排序:若排序过程中要进行数据的内、外存交换,则称之为外部排序

  1. 按策略划分内部排序方法

1)  插入排序2选择排序3交换排序4归并排序5分配排序

插入排序

         思想:每次将一个待排序的记录,按其关键字大小插入到前面已经排好序的适当位置,直到全部记录被插入完成为止。

  1. 1.       直接插入排序:

1)基本思想:假设待排序的记录存放在数组R[0n-1]中,初始时,R[0]自成一个有序区,无序区为R[1n-1].i起直至i=n-1为止,依次将R[i]插入当前的有序区R[0i-1]中,生成含n个记录的有序区

直接插入排序的基本操作是将当前无序区的第1个记录R[i]插入到有序区R[0i-1]中的适当位置,使R[0i]变为新的有序区,因为这种方法每次使有序区增加一个记录,通常称为增量法

插入排序与打扑克牌时整理手上的牌非常类似。摸来的第一张牌不用整理,此后每次从桌上的牌(无序区)中摸最上面的1张并插入左手的牌(有序区)中正确的位置。为了找到这个正确的位置,须自左至右(或自右至左)将摸来的牌与左手中的牌逐一比较

2)  示意图如下

第十章实现排序算法 插入排序_数据结构

3)  直接插入排序的时间复杂度为On2

直接插入排序的算法实现为:

///<summary>

        /// 直接插入排序

        /// </summary>

        /// <paramname="arr"></param>

        /// <returns></returns>

         public static int[]DirectInsertSort(int [] arr)

        {

            int len=arr.Length;

            for (int i = 1; i < len; i++)

            {

                for (int j = i-1; j >= 0;j--)

                {

                    if (arr[j+1] < arr[j])//相邻的交换

                    {

                        int tmp = arr[j+1];

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

                        arr[j] = tmp;

                    }

                    else

                    {

                        break;

                    }

                }

            }

            return arr;

        }

2.       希尔排序

希尔排序是一种插入排序

1)基本思想:对待排记录序列进行“宏观”调整,再进行微观调整。

所谓“宏观”调整,指的是“跳跃式”的插入排序。即将记录序列分成若干个子序列,每个子序列分别进行插入排序。关键是,这种子序列不是由相邻的记录构成的。假设将n个记录分成d个子序列,则这d个子序列分别为:

{R[1]R[1+d]R[1+2d],…,R[1+kd]}

{R[2]R[2+d]R[2+2d],…,R[2+kd]}

{R[d]R[2d]R[3d],…,R[(k+1)d]

 2)示意图为:

.第十章实现排序算法 插入排序_排序_02

第十章实现排序算法 插入排序_数据结构_03

第十章实现排序算法 插入排序_排序_04

第十章实现排序算法 插入排序_数据结构_05

3).     希尔排序的时间复杂度为Onlog2n2

4).     代码实现:

///<summary>

        /// 直接插入排序

        /// </summary>

        /// <paramname="arr"></param>

        /// <returns></returns>

public static int[] shellSort(int[] arr)

         {

             int d = 3;//假设当前增量为3

             while (d > 0)//排序的趟数

             {

                 for (int i = 0; i < d;i++)//分成d段分别进行插入排序

                 {

                     for (int j = i; j<arr.Length; j+=d)//插入排序

                     {

                         for (int k = j-d; k>= 0; k -= d)//与之前的进行比较,找到合适的位置,并交换

                         {

                             if (arr[k + d]< arr[k])

                             {

                                 int tmp =arr[k + d];

                                 arr[k + d] = arr[k];

                                 arr[k] = tmp;

                             }

                             else

                             {

                                 break;

                             }

                         }

                     }

                 }

                 d--;

             }

             return arr;

         }