插入排序 | 选择排序 | 冒泡排序

插入排序

将待排序的数据插入到已经排好序的数列中去。过程:依次与已排好序中的数据进行比较,从而找到适合自己的位置,直至插入全部待排序的数据为止。

例如:arr = [2 , 5 , 3 , 1 , 6 ]

伪代码:

//写法1(最好不要这样写) 这样会让待排序数据与有序区所有数据两两比较,不会提前终止;
for (i=0;j<arr.length;i++) {
    for(j=i;j>0;j--)
    {
        if (arr[j]<arr[j-1])   //如果后面的数更大
            exchange;          //交换arr[j]和arr[j-1]的值
    }
}
//写法2(这样写好些)
for (i=0;j<arr.length;i++) {
  //这样写的好处是可以提前终止比较;因为前面是已排好序的数据,只要待排序数据不小于有序区最后一个数据,则不用继续比较了;
    for(j=i;j>0&&arr[j]<arr[j-1];j--) 
    {
        exchange;          //交换arr[j]和arr[j-1]的值
    }
}

初始状态:无序区就是全部的数据;有序区是空的[ ];

外层for循环的意义:取本次待排序的数据。例如第一次取arr[0];第二次取arr[1];

内层for循环的意义:依次将待排序的数据与已排好序的数据进行比较,直到找打适合它的位置;

 

举个实例,比如我们打牌一人一张摸牌的时候:

来第一张牌时直接放好;

来第二张牌时和第一张比较,放好;

第三张牌来时,和手上的2张的最后一张比较,比最后一张大,那就直接把第三章牌放最后就好了,不用再和前面的比较了;

选择排序

第一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。

伪代码:

for (var i = 0; i < len - 1; i++) {
        minIndex = i;                         //假设这个索引的值就是最小的
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {     // 寻找最小的数的索引
                minIndex = j;                 // 将最小数的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];              //交换arr[i]和arr[minIndex]
        arr[minIndex] = temp;
}

初始状态:无序区就是全部的数据;有序区是空的[ ];

外层for循环的意义:取无序区第一个数据,假设它就是无序区里最小的数据;注意条件是len-1!每轮从无序区取出了最小的数挪到前面,那么最后一个数就不用排了。

内层for循环的意义:用外层循环取到的数据,依次和无序区的数据进行比较,记录下最小的那个数值的索引;在内层循环结束后,将外层循环取到的数据和最小的数据交换;直到排完所有无序区的数据;

 

插入排序和选择排序的比较:

1、流程不一样;

插入排序:依次进行两两比较,不合适就交换位置,直到找到目标位置;

选择排序:通过比较找到目标位置,再直接交换,相当于一步到位; 交换的次数少;

2、在数据量大的情况下,插入排序比选择排序效率更高。

相比于选择排序,插入排序的一个优点是提前终止,不用遍历整个数组,因此,插入排序应该要比选择排序的效率更加的高效;

 

冒泡排序

每一轮排序后将最大的数排到最后去;

依次比较两个相邻的数,将大的数放后面。那么在经过一轮排序后,最大的数就移到最后去了;

所以第二轮排序,最后一个数就不用再参与比较了;

[2,5,3,1,6]
for (int i = 0; i < len-1; i++) { //为什么是len-1?因为len个数,只需要排len-1次就好了。
        //对待排序序列进行冒泡排序
        for (int j = 0; j < len - i - 1; j++) {  //为什么是N-i-1?因为if判断写的是和j+1比较;当i=0时,最后一轮比较的是a[3]和a[4]
            //相邻元素进行比较,当顺序不正确时,交换位置
            if (a[j] > a[j + 1]) {
               exchange;
            }
        }
    }

外层for循环的意义:控制内层循环要比较的数据;比如第一轮要比较完所有的数据,也就是比较到len-1(数组索引从0开始);第二轮则不用比较最后一个数据了,比较到len-2就行;

内层for循环的意义:依次比较两两相邻的数据,直至把最大的数排最后去;

 

End.

posted @ 2022-04-24 17:20  youreyebows  阅读(66)  评论(0编辑  收藏  举报