zoukankan      html  css  js  c++  java
  • C#排序算法总结

           有一点我们很容易忽略的是排序算法的稳定性(腾讯校招2016笔试题曾考过)。

      排序算法稳定性的简单形式化定义为:如果Ai = Aj,排序前Ai在Aj之前,排序后Ai还在Aj之前,则称这种排序算法是稳定的。通俗地讲就是保证排序前后两个相等的数的相对顺序不变。

      对于不稳定的排序算法,只要举出一个实例,即可说明它的不稳定性;而对于稳定的排序算法,必须对算法进行分析从而得到稳定的特性。需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。

      例如,对于冒泡排序,原本是稳定的排序算法,如果将记录交换的条件改成A[i] >= A[i + 1],则两个相等的记录就会交换位置,从而变成不稳定的排序算法。

      其次,说一下排序算法稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,前一个键排序的结果可以为后一个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位排序后元素的顺序在高位也相同时是不会改变的。

      一.冒泡排序(Bubble Sort)

       1.基本思想:两个数比较大小,较大的数下沉,较小的数冒起来。

       2.过程:

          1.比较相邻的两个数据,如果第二个数小,就交换位置。

          2.从后向前两两比较,一直到比较最前两个数据。最终最小数被交换到起始的位置,这样第一个最小数的位置就排好了。

          3.继续重复上述过程,依次将第2.3...n-1个最小数排好位置。

      

        3.平均时间复杂度:O(n2)

        4.C#代码实现:

        

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace BubbleSort
    {
        //冒泡排序类
        public class BubbleSorter
        {
            public void Sort(int[] list)
            {
                int i, j, temp;
                bool done = false;
                j = 1;
                while ((j < list.Length) && (!done))
                {
                    done = true;
                    for (i = 0; i < list.Length - j; i++)
                    {
                        if (list[i] > list[i + 1])
                        {
                            done = false;
                            temp = list[i];
                            list[i] = list[i + 1];
                            list[i + 1] = temp;
                        }
                    }
                    j++;
                }
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                int[] iArrary = new int[] { 1, 5, 13, 6, 10, 55, 99, 2, 87, 12, 34, 75, 33, 47 };
                BubbleSorter sh = new BubbleSorter();
                sh.Sort(iArrary);
                for (int m = 0; m < iArrary.Length; m++)
                    Console.Write("{0}", iArrary[m]+",");
                Console.WriteLine();
                Console.ReadKey();
            }
        }
    }

      二. 选择排序(SelctionSort)

        1.基本思想:

        在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
        第二次遍历n-2个数,找到最小的数值与第二个元素交换;
        。。。
        第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。

        2.过程:

     

        3.平均时间复杂度:O(n2)

        4.C#代码实现:

        

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SelectionSort
    {
        //Selection Sort
        //在长度为N的无序数组中,第一次遍历n-1个数,找到最小的数值与第一个元素交换;
        //第二次遍历n-2个数,找到最小的数值与第二个元素交换;
        //。。。
        //第n-1次遍历,找到最小的数值与第n-1个元素交换,排序完成。
        public class SelectionSorter
        {
            private int min;
            public void Sort(int[] list)
            {
                for (int i = 0; i < list.Length - 1; i++)
                {
                    min = i;
                    for (int j = i + 1; j < list.Length; j++)
                    {
                        if (list[j] < list[min])
                            min = j;
                    }
                    int t = list[min];
                    list[min] = list[i];
                    list[i] = t;
                }
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                int[] iArrary = new int[] { 1, 5, 3, 6, 10, 55, 9, 2, 87, 12, 34, 75, 33, 47 };
                SelectionSorter ss = new SelectionSorter();
                ss.Sort(iArrary);
                for (int m = 0; m < iArrary.Length; m++)
                    Console.Write("{0}", iArrary[m]+",");
                Console.WriteLine();
                Console.ReadKey();
            }
        }
    }

      

      三. 插入排序(Insertion Sort)

        1.基本思想:

        在要排序的一组数中,假定前n-1个数已经排好序,现在将第n个数插到前面的有序数列中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。

        2.过程:

      

        

        3.平均时间复杂度:O(n2)

        4.C#代码实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace InsertionSort
    {
        public class InsertionSorter
        {
            public void Sort(int[] list)
            {
                for (int i = 1; i < list.Length; i++)
                {
                    int t = list[i];
                    int j = i;
                    while ((j > 0) && (list[j - 1] > t))
                    {
                        list[j] = list[j - 1];
                        --j;
                    }
                    list[j] = t;
                }
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                int[] iArrary = new int[] { 1, 13, 3, 6, 10, 55, 98, 2, 87, 12, 34, 75, 33, 47 };
                InsertionSorter ii = new InsertionSorter();
                ii.Sort(iArrary);
                for (int m = 0; m < iArrary.Length; m++)
                    Console.Write("{0}", iArrary[m]+",");
                Console.WriteLine();
                Console.ReadKey();
            }
        }
    }

       

      四. 希尔排序(Shell Sort)

        1.前言:

        数据序列1: 13-17-20-42-28 利用插入排序,13-17-20-28-42. Number of swap:1;
        数据序列2: 13-17-20-42-14 利用插入排序,13-14-17-20-42. Number of swap:3;
        如果数据序列基本有序,使用插入排序会更加高效。

        2.基本思想:

        在要排序的一组数中,根据某一增量分为若干子序列,并对子序列分别进行插入排序。
        然后逐渐将增量减小,并重复上述过程。直至增量为1,此时数据序列基本有序,最后进行插入排序。

        3.过程:

        4.平均时间复杂度:O(nlogn) ~ O(n^2)

        5.C#代码实现:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ShellSort
    {
        public class ShellSorter
        {
            public void Sort(int[] list)
            {
                int inc;
                for (inc = 1; inc <= list.Length / 9; inc = 3 * inc + 1) ;
                for (; inc > 0; inc /= 3)
                {
                    for (int i = inc + 1; i <= list.Length; i += inc)
                    {
                        int t = list[i - 1];
                        int j = i;
                        while ((j > inc) && (list[j - inc - 1] > t))
                        {
                            list[j - 1] = list[j - inc - 1];
                            j -= inc;
                        }
                        list[j - 1] = t;
                    }
                }
            }
        }
        class Program
        {
            static void Main(string[] args)
            {
                int[] iArrary = new int[] { 59,20,17,13,28,14,23,83 };
                ShellSorter sh = new ShellSorter();
                sh.Sort(iArrary);
                for (int m = 0; m < iArrary.Length; m++)
                    Console.Write("{0}", iArrary[m]+",");
                Console.WriteLine();
                Console.ReadKey();
            }
        }
    }

         参考:http://www.cnblogs.com/eniac12/p/5329396.html

            http://www.runoob.com/w3cnote/sort-algorithm-summary.html

            http://www.cnblogs.com/zxjyuan/archive/2010/01/06/1640092.html

    道虽迩,不行不至;事虽小,不为不成。
  • 相关阅读:
    git如何将一个远程仓库的某个分支拉取到当前分支?
    linux下如何检查内核补丁是否符合社区代码规范?
    javascript快速入门20--Cookie
    javascript快速入门19--定位
    javascript快速入门18--样式
    javascript快速入门17--事件
    javascript快速入门16--表格
    javascript快速入门15--表单
    javascript快速入门15--节点
    javascript快速入门14--DOM基础
  • 原文地址:https://www.cnblogs.com/LeeMacrofeng/p/8342277.html
Copyright © 2011-2022 走看看