冒泡 插入 选择排序

一:冒泡排序

算法原理:顾名思义,冒泡,最大的元素可理解成通过冒泡的形式筛选出来。对于一个数组来说,a[0]、a[1]、a[2]、a[3]....a[n],从a[0] a[1]、a[1] a[2]、a[2] a[3]....a[n-1] a[n]进行两两比较,如果前面的元素值比后面的大,则进行交换处理,例如a[0]>a[1],则进行int temp = a[0],a[0]=a[1] a[1]=temp处理,通过一轮的比较之后,a[n]就是整个数组中最大的元素了;同样进行第二轮的比较,则a[n-1]就是整个数组中第二大的元素...进行第三轮,a[n-2]的元素为数组中第三大的元素;最后进行第n-1轮,a[2]元素为数组中第n-1大的元素。(优化:如果某一轮的比较中,没有元素交换,即数组已经是有序的,可退出for循环,结束整个冒泡排序)

原始数列:6,5,4,3,2,1

第一次冒泡排序 5,4,3,2,1,6

第二次冒泡排序 4,3,2,1,5,6

第三次冒泡排序 3,2,1,4,5,6

第四次冒泡排序 2,1,3,4,5,6

第五次冒泡排序 1,2,3,4,5,6

代码:

/**
 * 冒泡排序
 * @param originalArray
 * @return
 */
public Integer[] bubblingSort(Integer[] originalArray){

    int length = originalArray.length;
    for (int i = length -1; i > 0; i--) {
        //提前退出冒泡循环的标记位
        boolean flag = false;
        for (int j = 0; j < i ; j++) {
            int a = originalArray[j];
            int b = originalArray[j + 1];
            if (a > b){
                int temp = a;
                originalArray[j] = originalArray[j+1];
                originalArray[j+1] = temp;
                flag = true; //有数据交换
            }
        }
        printArray(originalArray);
        System.out.println();
        //没有数据交换,提前退出
        if (!flag){
            break;
        }
    }
    System.out.print("最终的排序结果");
    printArray(originalArray);
    return originalArray;
}

运行结果:

空间复杂度:只涉及相邻数据的交换操作,只需要常量级的临时空间,空间复杂度为o(1),是一个原地排序算法。

时间复杂度:

最好时间复杂度:元素本身是有序排列的(从小到大),只需进行一次冒泡比较即可,所以时间复杂度为O(n)。

最坏时间复杂度:元素刚好是倒序排列的(从大到小),时间复杂度为O(n(n-1)/2),即为O(n2)。

平均时间复杂度:由上面最坏时间复杂的情形可知,需要比较n(n-1)/2次,可以取个中间值n(n-1)/4,n足够大,就可理解成n2,所以平均时间复杂度为O(n2)。

二:插入排序

算法原理:一个无序的数组,依次取a[1]和a[0]进行比较,按照从小到大排成一个有序数组,a[2]和前面的a[1]进行比较且记录value=a[2],如果value>a[1],则a[2]插入的位置不变,如果value<a[1],则a[2]=a[1],a[2]的值插入到a[1]的位置;继续进行比较value<a[0], 则a[1]=a[0],最后a[0]=value,依次类推

代码:

/**
 * 插入排序
 * @param a
 * @param n
 */
public void insertionSort(Integer[] a,int n){
    printArray(a);
    System.out.println("插入排序");
    for (int i = 1; i < n; i++) {
        int value = a[i];
        int j = i -1;
        for (; j >= 0 ; j--) {
            if (a[j] > value){
                a[j+1] = a[j];//数据移动
            }else{
                printArray(a);
                break;
            }
        }
        //发生插入排序,往前,给相应的元素赋值
        a[j + 1] = value;
        printArray(a);
    }
}

运行结果:

空间复杂度:插入排序算法不需要额外的存储空间,所以空间复杂度是O(1),也是个原地排序算法。

最好时间复杂度:元素本身是有序的,从尾到头在有序数组里面查找插入位置,每次只需比较一个数据就能确定插入的位置,所以为O(n)。

最坏时间复杂度:元素是倒序的,比较1次、2次、3次....n-1次,为O(n2)

平均时间复杂度:也为o(n2)

三:选择排序

算法原理:分有序区和无序区,在无序区中找到最小的元素,和有序区后的第一个元素进行替换。例如原始数组为4,5,6,3,2,1

第一次选择排序:1,5,6,3,2,4(1和4交换)

第二次选择排序:1,2,6,3,5,4(2和5交换)

第三次选择排序:1,2,3,6,5,4(3和6交换)

第四次选择排序:1,2,3,4,5,6(4和6交换)

第五次选择排序:1,2,3,4,5,6(5和6不用交换)

代码:

/**
 * 选择排序
 * @param a
 * @param n
 */
public static void selectionSort(Integer[] a,int n){
    printArray(a);
    System.out.println("插入排序");
    for (int i = 0; i < n; i++) {
        int min = i;
        for (int j = i + 1; j < n; j++) {
            //前后元素进行比较,后面的元素小于前面的元素,记录出最小元素的下标
            if (a[min] > a[j]){
                min = j;
            }
        }

        //最小元素的下标大于前面比较元素的下标,元素值进行交换
        if (i < min){
            int temp = a[min];
            a[min] = a[i];
            a[i] = temp;
        }
        printArray(a);
    }
}

运行结果:

空间复杂度为O(1),最好、最坏以及平均时间复杂度均为O(n2)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值