冒泡插入选择3种排序

冒泡排序

/**
 *步骤:
 * 1.比较相邻的元素,如果第一个比第二个大,就交换它们两个
 * 2.对每一个相邻元素作相同的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该就是最大的数
 * 3.针对所有的元素重复以上的步骤,除了最后一个
 * 4/重复步骤1~3,直到排序完成
 *
 * 总结:
 * 1.冒泡排序的时间复杂度是多少?
 * 最好情况下,要排序的元素已经是有序的了,我们只需要进行一次冒泡排序,就可以结束了,所以最好情况时间
 * 复杂度是O(n),而最坏的情况是,要排除的数据刚好是倒序排列的,我们需要进行n次冒泡操作,所以最坏情况
 * 时间复杂度为O(n²)。
 * 2.冒泡排序的空间复杂度是多少?
 * 冒泡的过程只涉及相邻数据的交换操作,只需要常量级的临时空间,所以它的空间复杂度为O(1),是一种in-place
 * 排序算法
 * 3.冒泡排序是稳定的排序算法吗?
 * 在冒泡排序中,只有交换才可以改变两个元素的前后顺序,为了保证冒泡排序算法的稳定性,当有相邻的连个元素
 * 大小相等的时候,我们不做交换,相同大小的数据在排序前后不会改变顺序,所以冒泡排序是稳定的排序算法
 */
public class BubbleSort {

    public static void main(String[] args) {

        int[] arr = new int[]{1,2,4,3,21,2,4,5,65,25,42,54,25};

        BubbleSort bubbleSort = new BubbleSort();

        bubbleSort.bubbleSort(arr);

        System.out.println(Arrays.toString(arr));

    }
    public void bubbleSort(int[] arr){
        int length = arr.length;
        if (length<0) {
            return;
        }
        for (int i=0;i<length;i++) {
            for (int j=i+1;j<length;j++) {
                if (arr[i]>arr[j]) {
                    int temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

}

插入排序

/**
 * 原理:将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序
 * 区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间
 * 中的元素,在已排序区间中会找到合适的插入元素将其插入,并保证已排序区间数据
 * 一直有序,重复这个过程,直到未排序区间中元素为空,算法结束。
 * 算法描述:
 * 1。从第一个元素开始,该元素可以认为已经被排序
 * 2.取出下一个元素,在已经排序的元素序列中从后往前扫描
 * 3.如果该元素(已排序)大于新元素,比如26543>265,就把26543的位置往后挪
 * 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置,比如26543的前一个
 * 元素为32,但这时候preIndex--,所以这时候preIndex其实所在位置是32所在位置
 * 因此赋值的时候是arr[preIndex+1] = current,即把原本26543的位置顶掉
 * 5。重复2-5步骤,即进入下一次for循环,向未排序的数组中再取数值
 *
 * -------------------------------------------------------------------------
 *
 * 1.插入排序的时间复杂度是多少
 * 如果要排序的数据已经是有序的话,我们并不需要搬任何数据。如果我们从尾到头在
 * 有序数据组里面查找插入位置,每次只需要比较一个数据就能去欸的那个插入的位置。
 * 所以这种情况下,最好时间复杂度为O(n)。注意这里是从尾到头遍历已经有序的数据
 *
 * 如果数组的倒序的,每次插入都相当于在数组的第一个位置插入新的数据,所以需要
 * 移动大量的数据,所以最坏情况时间复杂度为O(n²)
 * 2。插入排序的空间复杂度是多少?
 * 插入算法并不需要额外的存储空间,所以空间复杂度是O(1)
 *
 * 3.插入排序是稳定的排序算法吗?
 * 在插入排序中,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现元素
 * 的后面,这样就可以保持原有的前后顺序不变,所以插入排序是稳定的排序算法
 *
 * 4.插入排序是直接将未排序的往已排序里面砸,进行重复比较
 */
public class InsertionSort {

    public static void main(String[] args) {

        int[] arr = new int[]{32,5,4,26543,265,27,52,75,3,7,9};
        InsertionSort insertionSort = new InsertionSort();
        insertionSort.insertionSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    public void insertionSort(int[] arr) {
        //获取当前数组长度
        int len = arr.length;
        //说明数组只有1个元素或者没有元素
        if (len<=1) {
            return;
        }

        //从下标为1,即第二个元素开始对第一个元素进行比较,第一个元素已经排序好了
        for (int i=1;i<len;i++) {

            //取出当前序列中未排序的元素,即当前要和已排序区间比较的元素
            //这里用于记录当前元素
            int current = arr[i];
            //在有序区间从后往前扫描指针(下标)
            //当i=1时,i-1=0
            int preIndex = i - 1;
            //当下标>=0,即一直循环
            //arr[preIndex]>current 当前取出的元素大于要比较的元素
            while (preIndex>=0&&arr[preIndex]>current) {
                /*大的往后排,小的往前排
                前一个数和后一个数进行比较,如果前一个大的话,就把前一个数
                赋值给后一个数,重复循环至下标越界
                 */
                arr[preIndex+1] = arr[preIndex];
                /*下标--,即前一个继续比较,也用于放置位置,比如26543和265,265的位置其实是i
                26543的位置是i-1,我这里用26543,26543会将265的值覆盖
                 */
                /*
                这时候再--就是32的值了,32的值与current进行比较,即与265进行比较,不符合条件退出
                 每次比较过后,preIndex要--即与前一个进行比较
                 */
                preIndex--;
            }
            //这时候preIndex+1,即32往后退一个,则原本26543的位置会被265取代
            arr[preIndex+1] = current;
        }
    }
}

选择排序

/**
 * 原理:
 * 分已排序区间和未排序区间,选择排序每次会从未排序区间中
 * 找到最小的元素,将其放到已排序的末尾
 *
 * 总结
 * 1.排序的时间复杂度是多少?
 * 最好情况时间复杂度为O(n²),最坏情况时间复杂度为O(n²)
 * 2。选择排序的空间复杂度是多少?
 * O(1)
 * 3.选择排序是一个稳定的排序算法吗?
 * 选择排序不是一个稳定的排序算法,[4,5,4,1,5],在第一个排序的时候会将下标为3的1和下标
 * 为0的4进行替换,则原本下标为1的4和下标为2的4顺序变了,不稳定
 */
public class SelectionSort {
    public static void main(String[] args) {

    }

    public void selectionSort(int[] arr) {
        int len = arr.length;
        if (len <= 1) {
            return;
        }

        for (int i=0;i<len;i++) {
            //这里是计算位置,从未排序的进行选择,即i之前的都是排序好的
            int minIndex = i;
            //从未排序的序列中找到最小值
            for (int j=i;j<len;j++) {
                if (arr[j]<arr[minIndex]) {
                    minIndex = j;
                }
            }
            //记录当前元素
            int curr = arr[i];
            //将未排序的最小的元素赋给当前元素,即实现最小元素的插入
            arr[i] = arr[minIndex];
            //这里其实是进行了一个元素的互换
            arr[minIndex] = curr;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值