几种常用排序算法温习

一、 简单排序方法

1.直接插入排序

基本思想:顺序地将待排序的记录按其关键码的大小插入到已排序的记录子序列的适当位置。

算法代码

 //直接插入排序
        public static void InsertSort(SeqList<int> seq)
        {
            if (seq.IsEmpty() || seq.GetLength() == 1)
                return;
            Console.Write("1.1 简单排序  排序前:");
            seq.Display();
            int tmp;
            for (int i = 1; i < seq.GetLength(); i++)
            {
                if (seq[i] < seq[i - 1])
                {
                    tmp = seq[i];
                    int j;
                    for (j = i - 1; j >= 0 && tmp < seq[j]; j--)
                    {
                        seq[j + 1] = seq[j];
                    }
                    seq[j + 1] = tmp;
                }
                Console.Write("i={0}   ", i);
                seq.Display();
            }
        }
       备注:这里的SeqList<T>是自定义顺序表,这里就不详述了。

image

直接插入排序时间复杂度与顺序表的有序性有关,基本在o(n)到o(n2)之间。该算法是稳定的。若排序记录的数目 n 较小(如 n≤50)时,可采用直接插入排序或简
单选择排序。

2.冒泡排序

基本思想:将相邻的记录的关键码进行比较,如果前面记录的关键码大于后面记录的关键码,则将它们交换,否则不交换。

算法代码

//冒泡排序
        public static void BubbleSort(SeqList<int> seq)
        {
            if (seq.IsEmpty() || seq.GetLength() == 1)
                return;
            Console.Write("1.2 冒泡排序  排序前:");
            seq.Display();
            int tmp;
            for (int i = 0; i < seq.Last;i++)
            {
                for (int j = seq.Last-1; j >= i; j--)
                {
                    if (seq[j + 1] <seq[j])
                    {
                        tmp = seq[j];
                        seq[j] = seq[j + 1];
                        seq[j + 1] = tmp;
                    }
                }
                Console.Write("i={0}   ", i);
                seq.Display();
            }
        }

image

时间复杂度:最好O(n),最坏O(n^2)。它是稳定的。

3.简单排序算法

基本思想:每一趟在n-i+1(i=1,2,…,n-1)个记录中选取关键字最小的记录作为有序序列的第i个记录。

算法代码

//简单选择排序
        public static void SimpleSelectSort(SeqList<int> seq)
        {
            if (seq.IsEmpty() || seq.GetLength() == 1)
                return;
            Console.Write("1.3 简单选择排序  排序前:");
            seq.Display();
            int tmp;
            int index;
            for (int i = 0; i < seq.Last; i++)
            {
                index = i;
                for (int j = i; j <= seq.Last; j++)
                {
                    if (seq[j] < seq[index])
                    {
                        index = j;//找到最小元素下标
                    }
                }
                tmp = seq[i];//交换
                seq[i] = seq[index];
                seq[index] = tmp;
                Console.Write("i={0}   ", i);
                seq.Display();
            }
        }

image

时间复杂度:O(n^2),它是稳定的排序。若记录的初始状态已经按关键码基本有序,可采用直接插入排序或冒泡排序。

二、快速排序

基本思想:通过不断比较关键码,以某个记录为界(该记录称为支点) ,将待排序列分成两部分。其中,一部分满足所有记录的关键码都大于或等于支点记录的关键码,另一部分记录的关键码都小于支点记录的关键码。把以支点记录为界将待排序列按关键码分成两部分的过程,称为一次划分。对各部分不断划分,直到整个序列按关键码有序为止。

算法代码

//快速排序,递归,以第一个元素为支点
       public static void QuickSort(SeqList<int> seqlist, int low, int high)
       {
           int tmplow = low;//临时保存开头元素索引
           int tmphigh = high;//临时保存结束元素索引
           int tmp = seqlist[low];
           if (low >= high)
               return;
           while (low < high)
           {
               while (low < high && seqlist[high] >= tmp)
                   high--;
               seqlist[low] = seqlist[high];
               while (low < high && seqlist[low] <= tmp)
                   low++;
               seqlist[high] = seqlist[low];
           }
           seqlist[low] = tmp;
           seqlist.Display();
           QuickSort(seqlist, tmplow, low - 1);
           QuickSort(seqlist, low + 1, tmphigh);
       }

image

时间复杂度:快速排序方法的平均性能最好,时间复杂度为O(nlog2n),当待排序序列已经按关键码随机分布时,快速排序是最适合的。但快速排序在最坏情况下时间复杂度是O(n2)。快速排序方法是不稳定的排序方法。

原文地址:https://www.cnblogs.com/janes/p/2231567.html