• c#排序算法详细探究


    算法的确比较头痛。在学校的时候也没好好学。工作的时候用的也不多。但每次面试时候还是心虚的把这些东西都翻出来看看。其实也看不懂。基本就是死记硬背了。唉。这次要好好看看
    第一个:冒泡算法。
    昨天晚上吧程序员教程翻出来看看。说这个冒泡算法的原理:两个元素比较谁大谁就沉低。想水泡一样。具体是这样的。一组数字进行比较。第一个数和第二个比较。如果第一个小于第二个就不替换他们原来的位置。如果第一个比第二大那么把第一个和第二个位置交换一下。然后第二个继续和第三个比较。依次推理。
    代码方法:
    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++;
     }
     
     }
    第一次内循环。先把长度-1之前的数字两两进行比较。之后的结果。就是把最大的数字排到最后。然后下次在循环的时候就是直接比较长度-2之前的数字了。因为之前最大的数字已经被替换到最后面了。不用比较了。
    注意那个done。如果内循环里面一次替换都没有发生说明现在已经是按顺序排好了。不用再循环了。
    其他也没什么好说的,包括替换就不说了。
    这是个人看法。大家说说意见。


    /// <summary>
            /// 冒泡排序
            /// </summary>
            /// <param name="array"></param>
            static void BubbleSort(ref int[] array)
            {
              
                for (int n = 0; n < array.Length; n++)
                {
                    bool flag = false;
                    for (int m = 0; m < array.Length - 1 - n; m++)
                    {
                        if (array[m] > array[m + 1])
                        {
                            int temp = array[m+1];
                            array[m+1] = array[m];
                            array[m] = temp;
                            flag = true;
                        }
                    }
                    if (flag != true)
                    {
                        return;
                    }
                }
            }

    第二个:选择排序算法。
    选择排序算法的基本思路是第一个数字依次和后面每个数字进行比较。而不想冒泡一样是两两比较替换。选择排序算法也是采用内外循环两次。外循环先使第一个数字和后面每个数字进行比较。如果第二个数字比第一个大则不做处理。如果第二个数字比第一个小则做处理。这里的处理不是直接交换两个数字的位置。而是把他们的位置也是下标得到。有个全局变量外循环第一次是这数字min=0;表示当前最小的数字下标是0.内循环内进行比较如果第二个数字比第一个数字还小。则min = 1也就是第二个数字的下标。然后依次下去得到最小数字的下标。退出循环后把第一个数字和min位置的数字替换一下了
    public void  SelectSort(int[] list)
      {
          int min ;
           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的值
                        min = j;
                }//退出循环以后把min位置处的数字和i数字替换
                int t = list[min];
                list[min] = list[i];
                list[i] = t;

            }
     }

    这样循环就是n-i的次数了。不是全部循环

    第三个:快速选择排序算法

    快速排序是对冒泡排序的一种改进。它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

       假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。一躺快速排序的算法是:

      1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;

      2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];

      3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;

      4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;

      5)、重复第3、4步,直到I=J;

      例如:待排序的数组A的值分别是:(初始关键数据X:=49)

                      A[1]    A[2]    A[3]    A[4]    A[5]     A[6]    A[7]: 

                        49       38      65      97      76      13       27

    进行第一次交换后:  27       38      65      97      76      13       49

                      ( 按照算法的第三步从后面开始找

    进行第二次交换后:  27       38      49      97      76      13       65

                     ( 按照算法的第四步从前面开始找>X的值,65>49,两者交换,此时I:=3 )

    进行第三次交换后:  27       38      13      97      76      49       65

    ( 按照算法的第五步将又一次执行算法的第三步从后开始找

    进行第四次交换后:  27       38      13      49      76      97       65

    ( 按照算法的第四步从前面开始找大于X的值,97>49,两者交换,此时J:=4 )

         此时再执行第三不的时候就发现I=J,从而结束一躺快速排序,那么经过一躺快速排序之后的结果是:27       38      13      49      76      97       65,即所以大于49的数全部在49的后面,所以小于49的数全部在49的前面。

         快速排序就是递归调用此过程——在以49为中点分割这个数据序列,分别对前面一部分和后面一部分进行类似的快速排序,从而完成全部数据序列的快速排序,最后把此数据序列变成一个有序的序列,根据这种思想对于上述数组A的快速排序的全过程如图6所示:

     初始状态                       {49    38    65    97    76    13    27}   

    进行一次快速排序之后划分为     {27    38    13}    49  {76    97    65}

    分别对前后两部分进行快速排序   {13}   27   {38} 

                                   结束        结束   {49   65}   76   {97}

                                                       49  {65}        结束

                                                           结束

                             图6   快速排序全过程

    1)、设有N(假设N=10)个数,存放在S数组中;

    2)、在S[1。。N]中任取一个元素作为比较基准,例如取T=S[1],起目的就是在定出T应在排序结果中的位置K,这个K的位置在:S[1。。K-1] <=S[K]<=S[K+1..N],即在S[K]以前的数都小于S[K],在S[K]以后的数都大于S[K];

    3)、利用分治思想(即大化小的策略)可进一步对S[1。。K-1]和S[K+1。。N]两组数据再进行快速排序直到分组对象只有一个数据为止。

    如具体数据如下,那么第一躺快速排序的过程是:

    数组下标: 1     2     3     4     5     6     7     8     9     10

              45    36    18    53    72    30    48    93    15     36

         I                                                                  J

    (1)     36    36    18    53    72    30    48    93    15     45

    (2)     36    36    18    45    72    30    48    93    15     53

    (3)     36    36    18    15    72    30    48    93    45     53

    (4)     36    36    18    15    45    30    48    93    72     53

    (5)     36    36    18    15    30    45    48    93    72     53

    通过一躺排序将45放到应该放的位置K,这里K=6,那么再对S[1。。5]和S[6。。10]分别进行快速排序


    其实简单的说就是选择一列数据中的一个关键字。把大于他的放的后面小于他的放在前面。一分为二。依次递归下去。当然这个速度的快慢和你选择这个关键字关系比较大
    c#代码:

    public void quickSort(int[ ] a,int left, int right)     //left为数组a第一个元素位置,right为数组a最后一个元素位置
            {
                int i, j, pivot, temp;     //pivot为支点
                if (left >= right)
                    return;
                i = left;
                j = right + 1;
                pivot = a[left];
                while (true)
                {
                    do
                    {
                        i++;
                    } while (a[i] < pivot && i < right);     //从左向右寻找大于支点元素 
                    do
                    {
                        j--;
                    } while (a[j] > pivot && j > 0);     //从右向左寻找小于支点元素
                    if (i >= j)
                        break;
                    else     //满足i<j则交换i和j位置元素值
                    {
                        temp = a[i];
                        a[i] = a[j];
                        a[j] = temp;
                    }
                }
                a[left] = a[j];
                a[j] = pivot;     //以a[j]为新支点,j位置左边元素值均小于a[j],j位置右边元素值均大于a[j]
                quickSort(a, left, j - 1);      //递归排序
                quickSort(a, j + 1, right);
            }


    插入排序法
    原理研究中。呵呵。今天只贴这个代码吧。
    public static void SortByInsert(int[] list)
            {
                for (int i = 0; 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;
                }
                for (int m = 0; m < list.Length; m++)
                {
                    Console.Write(list[m] + ",");
                }
            }






    本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

  • 相关阅读:
    《Entity Framework 6 Recipes》中文翻译系列 (34) ------ 第六章 继承与建模高级应用之多条件与QueryView
    《Entity Framework 6 Recipes》中文翻译系列 (33) ------ 第六章 继承与建模高级应用之TPH与TPT (2)
    《Entity Framework 6 Recipes》中文翻译系列 (32) ------ 第六章 继承与建模高级应用之TPH与TPT (1)
    《Entity Framework 6 Recipes》中文翻译系列 (31) ------ 第六章 继承与建模高级应用之自引用关联
    《Entity Framework 6 Recipes》中文翻译系列 (30) ------ 第六章 继承与建模高级应用之多对多关联
    《Entity Framework 6 Recipes》中文翻译系列 (29) ------ 第五章 加载实体和导航属性之过滤预先加载的实体集合和修改外键关联
    《Entity Framework 6 Recipes》中文翻译系列 (28) ------ 第五章 加载实体和导航属性之测试实体是否加载与显式加载关联实体
    《Entity Framework 6 Recipes》中文翻译系列 (27) ------ 第五章 加载实体和导航属性之关联实体过滤、排序、执行聚合操作
    《Entity Framework 6 Recipes》中文翻译系列 (26) ------ 第五章 加载实体和导航属性之延缓加载关联实体和在别的LINQ查询操作中使用Include()方法
    《Entity Framework 6 Recipes》中文翻译系列 (25) ------ 第五章 加载实体和导航属性之加载完整的对象图和派生类型上的导航属性
  • 原文地址:https://www.cnblogs.com/zjypp/p/2319454.html
Copyright © 2020-2023  润新知