java排序算法(一)-冒泡排序、插入排序、选择排序

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

以下算法假设数组长度都为 n

冒泡排序

冒泡排序需要比较的轮次为n-1轮。
需要比较的次数为 n-1到1的等差数列求和 次(如果n为5,则为1+2+3+4次)。
原理为:从前两个数开始两两比较,如果前一个数大于后一个数则交换位置,一直比较到最后两个数时,就会将此数组中最大的一个数交换至最后。
然后进行第二轮比较,第二轮比较时不包含数组中最后一个数(下标n-1位置的数),因为最后一个数已经是最大的了,不需要再进行比较。第二轮比较完后下标n-2位置的数也已经是数组中第二大的数了,以此类推比较完n-1轮后,就已经是有序的数组了。
提前断开: 如果某轮比较中,没有进行任何交换,说明数组已经是有序的了,那可以直接停止所有循环,输出数组。
时间复杂度:O(N^2)
空间复杂度:O(1)
原地排序算法:是
稳定:是
冒泡排序算法如下:

package com.example.demo;

public class SortTest {

    public static void main(String[] args) {
        int[] arr = {7,4,1,5,2,8};
        mpSort(arr);
    }


    /**
     * 冒泡排序
     * 6位数比较5次,
     * 依次使用数组中相邻的两个数比较,把大的数往后移。
     * 如果某次没有移动,说明比较下来已经全部按顺序排列好了,要不然比较肯定会有数的移动。
     * @param arr
     */
    public static void mpSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
        	// 每轮是否有交换的记录,默认true为没有交换
            boolean flag = true;
            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;
                    flag = false;
                }
            }
            // 此轮没有数的交换则直接断开
            if (flag) {
                break;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
    
}

插入排序

插入排序,
原理:默认将数组中的下标为0个数当成第一个已经被插入的数。
排序时从下标i=1的数开始,将i=1的数记录到temp,依次与下标<i的数比较,如果小于i的数大于下标为i的数,则将<i的数向前移动一位,然后继续和再前一位数比较。
下标<i的数一定是有序的(所以如果i-1大于temp才有可能i-2也大于temp,如果i-1小于temp那么更前面的数肯定也小于temp,因为i前面的数都是有序的)。
如果小于i的数小于temp,那么终止比较,然后将temp插入到当前比较数的后一位(下标+1位)。
例如:3 2 1 4 5
temp=2;
下标为0的3>2 所以将下标为0的3后移一位,移动后 3 3 1 4 5
然后继续走循环后下标减减,得到下标为-1,然后-1是小于0的,所以断开循环,
然后再将temp插入到下标-1+1的位置,也就是下标为0的位置。得到2 3 1 4 5
这样前2位2 3就排序好了,后面的以此类推就可以了。类推后的数组如下
temp=1;
3>1,移动后如下:
2 3 3 4 5
2>1,移动后如下:
2 2 3 4 5
将temp插入后如下:
1 2 3 4 5
时间复杂度:O(N^2)
空间复杂度:O(1)
原地排序算法:是
稳定:是

	/**
	 * 插入排序
     * @param arr
     */
    public static void crSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int temp = arr[i];
            int j = i - 1;
            for (; j >= 0; j--) {
                if (arr[j] > temp) {
                    arr[j + 1] = arr[j];
                } else {
                    break;
                }
            }
            arr[j + 1] = temp;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }

选择排序

选择排序
原理:
选择排序第一次优先将数组最小的数插入到下标为i=0的数组下标中。
第二次将除开i=0的数中找出最小的数插入i=1的下标中。
第三次将除开i=0、i=1的数中找出最小的数插入到i=2的下标中。
依次类推,一直到数组长度的最后一个数。
逻辑:
先默认将当前循环下标的数值使用temp记录起来,因为它需要与后续最小的数交换位置。
然后默认当前循环下标的数为最小的数,记录他的下标min。
然后依次用下标最小的数与后面的数比较(注意这里是从数组最后的一个数开始与最小的数比较),
如果遇到比此数更小的数则将其替代min的下标值。
此次外围循环结束后就能找到当前数中的最小的数,然后与当前外围循环的下标位置交换,则已经排好一轮。
时间复杂度:O(N^2)
空间复杂度:O(1)
原地排序算法:是
稳定:否

	/**
	 * 选择排序
     * @param arr
     */
public static void xzSort(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            int temp = arr[i];
            int min = i;
            int j = arr.length - 1;
            for (; j > i; j--) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            arr[i] = arr[min];
            arr[min] = temp;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值