c#冒泡选择插入排序总结

冒泡排序

//外层循环控制趟数
for(int i=0;i<arr.length-1;i++)

{
//内层控制当前趟中比较的次数
    for(int j=0;j<arr.length-i-1;j++)

    {

        if(arr[j]>arr[j+1])

        {

            int temp=arr[j];

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

            arr[j+1]=temp;

        }

    }

}

冒泡排序就是在一趟趟的比较相邻的数据并交换的排序方法

首先有几个数据就需要排序多少趟减1,因为最后一趟就一个数没必要比较了

然后内层循环里面arr-length-i是把原先排序好的i给减去,没必要再比较排好序的数据

判断当前数和相邻的数的大小,如果大于后面的数据就进行交换,通过一次次的比较及交换就把当前趟中最大的数移到当前趟的最后面

选择排序

 powerAffairArray为list<AffairTemp>

int i, j;  //先定义一下要用的变量
                        AffairTemp temp;
                        for (i = 0; i < powerAffairArray.Length - 1; i++)
                        {
                            for (j = i + 1; j < powerAffairArray.Length; j++)
                            {
                              var temp1 = affairAcceptList.FirstOrDefault(o => o.AFFAIRID == powerAffairArray[i].AFFAIRID);
                             var temp2 = affairAcceptList.FirstOrDefault(o => o.AFFAIRID == powerAffairArray[j].AFFAIRID);
                             if ((temp1 != null ? temp1.TwoMonthsAcceptCount : 0) < (temp2 != null ? temp2.TwoMonthsAcceptCount : 0))
                                {
                                    temp = powerAffairArray[i];
                                    powerAffairArray[i] = powerAffairArray[j];
                                    powerAffairArray[j] = temp;
                                }
                            }
                        }

这个方法是公司项目实际使用的,目的是是所有的事项信息的数量进行排序,数量大的排在前面

外层循环和第一种方法一样,不做解释了

内层循环是把j的起始值设为i+1,且循环条件为小于数组的长度,这样其实是跟第一种方法中内层循环的次数一样

这个方式跟第一种方式最大的不同是比较的对象不一样,第一种是比较相邻的两个数据,通过把值更大的通过一次次比较和交换移到最前面,第二种方法是用第一个数据跟其他几个数据进行比较,如果有比第一个数据大的就进行交换

通过第一趟比较就能确定第一趟中最大的一个数,下一趟就让第二个数与后面的其他几个数比较,最终确定第二最大的数,依次进行,最终确定顺序

插入排序

for(int i=1;i<arr.length;i++)
{
     int temp=arr[i];
    for(int j=i;j>0&&arr[j-1]>temp;j--)
    {
        arr[j]=arr[j-1];
    }
    arr[j]=temp;
}

这个是把第一个数当成有序序列,然后把其他数插进去的方法

由于第一个数就是排序好的,所以i从1开始进行循环(即第二个数开始),把第二个数的值先存到变量中

内层循环中j的起始值为i,因为内层循环中循环的次数根据已排序的有序数列的长度确定

内层循环可以变形为

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

{

   if(arr[j-1]>temp)

   {

       arr[j]=arr[j-1];

   }

}

内层循环的次数和满足条件进行的处理分开,这样比较容易理解

循环控制比较的次数,需要跟已排序的序列进行比较,如果要插入的数据的值小于前面的数(已排序序列中最大的数)就让这个数移到他这个位置,然后继续循环,直到不满足条件为止

其实我这个变形只是为了好理解,不建议这样用,因为不满足条件有可能是j=0这种情况下跟变形后一样,另一种条件是arr[j-1]>temp如果不满足这个条件时说明前面的数没有我要插入的大,这样就不用改位置,再往前的也没必要比较了,可以更早的跳出循环

另外对于最后给arr[j]赋值,这个有点不太好理解,temp变量存的是要插入的数据,所以把这个值赋给要插入的位置这个是比较好理解的,首先假设条件不满足的话其实arr[j]=arr[i]=temp,因为不满足条件相当于没有进入循环,j初始值为i,如果循环的话会把j-1的值给j,那么j-1的位置就空出来了,而且进入循环后执行了j--,这样这时候的j就是刚才的j-1了,所以给arr[j]赋值就是给刚才空出来的j-1赋值

补充下循环的执行顺序

for(int i=0; i<5;i++)

{内容}

进入后先走i=0,然后判断i是否小于5,如果不小于5就跳过循环了,如果小于5才进入执行内容代码,执行完之后走i++,然后再进行判断i是否小于5,接下来就跟前面一样了

我们很容易就看出来,这个循环执行了五次,如果内容里面是对i进行操作就比较有意思了,比较内容为i++;这样的话就执行三次了

快速排序

void qSort(int[] arr,int left,int right)
{
    if(left<right)
    {
        int first=left;
        int last=right;
        int key=arr[first];
        while(first<last)
        {
            while(first<last&&arr[last]>=key)
            {
                last--;
            }
            arr[first]=arr[last];
            while(first<last&&arr[first]<=key)
            {
                first++;
            }
            arr[last]=arr[first];
        }
        arr[first]=key;
        qSort(arr,left,first-1);
        qSort(arr,first+1,right);
    }
}

快速排序就是先取到一个值作为基准,把小于这个值的放在左边,大于它的放在右边,然后递归执行,最后分成的序列为1个或0个数,排序也就结束了

假设序列为4 7 8 5 3 1

以4为基准,然后进入循环,从后往前查找,先判断最后一个值即1与4,不满足条件,然后把1放到4所在的位置,即178531,然后从前往后查大于4的,7大于4,就把7放到刚才1所在的位置,因为last还是指向1所在的位置,此时序列变成178537, last指向后面7所在位置即最后一位,first指向前面7所在位置,继续循环,3小于4,就把3赋给first指向的位置,也就是前面的7所在位置,序列变成138537,然后从前往后查大于4的,8大于4,把8放到last所在位置即后面3所在位置,前面8对应的是first位置,后面8对应last位置,然后序列变成138587,从后往前找小于4的,5大于4然后执行last--,last指向8,此时first和last指向同一个元素,不满足first<last的条件,然后arr[first]=arr[last]这个赋值就不起作用了,最后退出循环,又给arr[first]赋key值,也就是给前面的8赋4,最后序列变成134587

这个相比于其他三种比较难理解,快速算法应用的比较广泛,还是要好好学习的

猜你喜欢

转载自blog.csdn.net/qq_33380252/article/details/86505645