回炉篇5—数据结构(4)之冒泡、选择、插入排序算法

冒泡、选择、插入排序算法

排序大家都很熟了,很古老的算法,古老才有必要回炉再看一遍,经典才值得研究。

1.冒泡排序

从字面意思理解,水泡从水底冒出到水面的过程中,由小慢慢大,最后大泡泡冒出水面,了解这个物理现象就可,整个代码实现的思路也就是这样的。

步骤:
1.比较相邻元素。(若第一个比第二个大,换位)
2.每对相邻元素依次做同样工作,直到最后一对。(一轮结束,最后的元素最大,第一波冒泡完成)
3.对所有元素重复1、2步骤,除了最后一个数。
4.对越来越少的元素重复上面步骤,直到没有一对数字需要比较。
冒泡排序图
java代码

public class BubbleSort {
    public static int[] sort(int[] array){
        //这里for循环表示总共需要比较多少轮
        for(int i = 1 ; i < array.length; i++){
            //设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。
            boolean flag = true;
            //这里for循环表示每轮比较参与的元素下标
            //对当前无序区间array[0......length-i]进行排序
            //j的范围很关键,这个范围是在逐步缩小的,因为每轮比较都会将最大的放在右边
            for(int j = 0 ; j < array.length-i ; j++){
                if(array[j]>array[j+1]){
                    int temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;
                }
            }
            if(flag){
                break;
            }
            //第 i轮排序的结果为
            System.out.print("第"+i+"轮排序后的结果为:");
            display(array);
             
        }
        return array;
         
    }
     
    //遍历显示数组
    public static void display(int[] array){
        for(int i = 0 ; i < array.length ; i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
     
    public static void main(String[] args) {
        int[] array = {4,2,8,9,5,7,6,1,3};
        //未排序数组顺序为
        System.out.println("未排序数组顺序为:");
        display(array);
        System.out.println("-----------------------");
        array = sort(array);
        System.out.println("-----------------------");
        System.out.println("经过冒泡排序后的数组顺序为:");
        display(array);
    }
 
}

时间复杂度:
T(n)=O(n2).

2.选择排序

从字面意思理解,先选择需要的数,再将其放置需要的位置。
思路是每一次选择待排序集合中最小的数,将其放置序列起始位置,直到所有待排元素都被排完。

步骤:
1.带排序列中,找到关键字最小元素;
2.若最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
3.余下元素中,找到关键字最小的元素,重复2步骤;
4.重复3步骤,直到排序结束。
选择排序图
Java代码:

public class ChoiceSort {
    public static int[] sort(int[] array){
        //总共要经过N-1轮比较
        for(int i = 0 ; i < array.length-1 ; i++){
            int min = i;
            //每轮需要比较的次数
            for(int j = i+1 ; j < array.length ; j++){
                if(array[j]<array[min]){
                    min = j;//记录目前能找到的最小值元素的下标
                }
            }
            //将找到的最小值和i位置所在的值进行交换
            if(i != min){
                int temp = array[i];
                array[i] = array[min];
                array[min] = temp;
            }
            //第 i轮排序的结果为
            System.out.print("第"+(i+1)+"轮排序后的结果为:");
            display(array);
        }
        return array;
    }
 
    //遍历显示数组
    public static void display(int[] array){
        for(int i = 0 ; i < array.length ; i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
     
    public static void main(String[] args){
        int[] array = {4,2,8,9,5,7,6,1,3};
        //未排序数组顺序为
        System.out.println("未排序数组顺序为:");
        display(array);
        System.out.println("-----------------------");
        array = sort(array);
        System.out.println("-----------------------");
        System.out.println("经过选择排序后的数组顺序为:");
        display(array);
    }
}

时间复杂度:
T(n)=O(n2) (复杂度数量级相同,但是比冒泡要快,当n较小且交换时间比选择时间大的多时,相当快)

3.插入排序

直接插入排序基本思想是每一步将一个待排序的记录,插入到前面已经排好序的有序序列中去,直到插完所有元素为止。
这里介绍最简单的插入排序,其他高级的插入排序后面会题到。

步骤:
1.取出一个待排序元素,根据关键字大小将其放置到有序序列中。
2.再取出一个待排元素,根据关键字大小将其放置到有序序列中。
3.重复步骤2,直到没有待排元素为止。
插入排序
Java代码

public class InsertSort {
    public static int[] sort(int[] array){
        int j;
        //从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
        for(int i = 1 ; i < array.length ; i++){
            int tmp = array[i];//记录要插入的数据
            j = i;
            while(j > 0 && tmp < array[j-1]){//从已经排序的序列最右边的开始比较,找到比其小的数
                array[j] = array[j-1];//向后挪动
                j--;
            }
            array[j] = tmp;//存在比其小的数,插入
        }
        return array;
    }
     
    //遍历显示数组
    public static void display(int[] array){
        for(int i = 0 ; i < array.length ; i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();
    }
     
    public static void main(String[] args){
        int[] array = {4,2,8,9,5,7,6,1,3};
        //未排序数组顺序为
        System.out.println("未排序数组顺序为:");
        display(array);
        System.out.println("-----------------------");
        array = sort(array);
        System.out.println("-----------------------");
        System.out.println("经过插入排序后的数组顺序为:");
        display(array);
    }
  
}

时间复杂度:
T(n)=O(n2)

总结

经过介绍,对这三种排序会更好的理解,冒泡排序最慢,选择排序将交换次数降到最低,但是比较次数多,当数据量小,并且交换数据相对于比较数据更加耗时的情况下,可以应用选择排序。
在大多数情况下,假设数据量比较小或基本有序时,插入排序是三种算法中最好的选择。

Reference

Java数据结构和算法(三)——冒泡、选择、插入排序算法

猜你喜欢

转载自blog.csdn.net/qq_41741395/article/details/85052196