JavaSE学习总结(十一)常见八大排序算法冒泡排序选择排序直接插入排序希尔排序归并排序快速排序基数排序堆排序

JavaSE学习总结(十一)常见八大排序算法/冒泡排序/选择排序/直接插入排序/希尔排序/归并排序/快速排序/基数排序/堆排序

排序

一、冒泡排序

(一)原理

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

在这里插入图片描述

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        int t=0;
        for (int i = 0; i < a.length-1; i++) { //外层循环用于定义排序次数
            for(int j = 0;j < a.length-i-1; j++){ //j < a.length-i-1 定义每次排序比较的次数
                if(a[j]>a[j+1]){
                    t=a[j];
                    a[j]=a[j+1];
                    a[j+1]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

二、选择排序

(一)原理

第一种:从0索引开始,逐个和后面的所有元素进行比较,小的往前放,第一轮排序完后,最小的元素出现在了最小索引处;第二轮排序,从1索引开始…
在这里插入图片描述
第二种:第一次设定起始位置的元素为最小(大)元素,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序的序列的首部。以此类推,直到全部待排序的数据元素的个数为零。

(二)代码实现

第一种

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        int t=0;
        for (int i = 0; i < a.length-1; i++) { //外层循环定义排序次数 i为每次选择排序选择的元素的索引
            for(int j = i+1;j < a.length; j++){ //每次从索引为i的元素后开始比较
                if(a[i]>a[j]){
                    t=a[i];
                    a[i]=a[j];
                    a[j]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

在这里插入图片描述
第二种

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        for (int i = 0; i < a.length-1; i++) {//确定每次开始的位置
            int min=a[i];//假设每次起始的元素就是最小值
            int flag=i;//标记最小值所在的位置
            for(int j=i+1;j<a.length;j++){
                if(a[j]<min){//从开始索引向后一个个和min比较,再把最小值存放到min,并更新flag标记
                    min=a[j];
                    flag=j;
                }
            }
            if(min!=a[i]){//如果min和起始的索引的元素值不一致了,则交换min所在的索引元素和起始索引的元素
                a[flag]=a[i];
                a[i]=min;
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
}

在这里插入图片描述

三、插入排序

(一)原理

直接插入排序,是一种最简单的排序方法。他的基本操作是将一个记录插入到一个长度为m 的有序表中,使之仍保持有序,从而得到一个新的长度为m+1的有序列表。假设有一组无序元素{k1,k2…,kn},排序开始就认为k1是一个长度为1的有序序列,让k2按照大小顺序插入上述k1这个有序序列,使之成为一个表长为2的有序序列,然后让k3按照大小顺序插入上述表长为2的有序序列,使之成为一个表长为3的有序序列,以此类推,最后让kn插入表长为n-1的有序序列,得到一个表长为n的有序序列。

例如:
49,38,65,97,76,13,27 原始数据
[49],38,65,97,76,13,27 从1索引开始
[38,49], ,65,97,76,13,27
[38,49,65] 97,76,13,27
[38,49,65,97] 76,13,27
[38,49,65,76,97]13,27
[13,27,38,49,65,76,97],27
[13,27,27,38,49,65,76,97]

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a={24,69,80,57,13};
        for (int i = 1; i < a.length; i++) {//外层循环定义轮次
            for(int j=i;j>0;j--){//里层就是循环让当前元素和上一个有序列表中的每个元素比较,进行位置交换,使之仍保持有序
                if(a[j]<a[j-1]){
                    int t=a[j];
                    a[j]=a[j-1];
                    a[j-1]=t;
                }
            }
        }
        //打印结果
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+" ");
        }
    }
}

在这里插入图片描述

六、快速排序

(一)原理

  1. 先从数列中取出一个数作为基准数。
  2. 将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
  3. 再对左右区间重复第二步,直到各区间只有一个数。

举例
在这里插入图片描述
解析:首先将第一个元素6作为基准数,起初i和j索引分别在数组的首和尾,从j开始从后向前找比基准数6小的值,找到后停下,于是j在值5处停下;接着,i开始从前向后找比基准数大的数,找到后停下,于是i在值为7处停下,然后交换5和7。再接着,j继续向前移,找到比基准数小的4,然后i继续向后移,找到比基准数大的9,将4和9交换。接着,j继续前移,找到比基准数小的3,i再开始后移,也到了3的位置,i和j重合了,于是,将3和基准数6交换(i和j重合,就将基准数和该处元素交换)。至此,基准数6就排到了自己正确的位置,然而6两边的数还是无序的,因此又拆分成两个数组,重复上述的操作,直到所有的数都归位为止。

(二)代码实现

public class MyTest {
    public static void main(String[] args) {
        int[] a = {46, 55, 13, 42, 17, 94, 5, 70, 10, 30, 56, 1, 0, 20, 1, 5, -1};
        quickSort(a, 0, a.length - 1);
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + " ");
        }
    }
    private static void quickSort(int[] a, int startIndex, int endIndex) {
        if (startIndex < endIndex) {
            //获取归位后的基准数形成的左右分区的索引
            int index = getIndex(a, startIndex, endIndex);
            //对左右两个分区 再进行同样的步骤 ,即递归调用
            quickSort(a, startIndex, index - 1);
            quickSort(a, index + 1, endIndex);
        }
    }
    private static int getIndex(int[] a, int startIndex, int endIndex) {
        int index = startIndex;//定义基准数的索引
        int i = startIndex;
        int j = endIndex;
        int t = 0;//临时变量
        while (i < j) {
            while (i < j && a[j] >= a[index]) {//从右往左比较,找到比基准数小的数
                j--;
            }
            while (i < j && a[i] <= a[index]) {//从左往右比较,找到比基准数大的数
                i++;
            }
            //交换两个数
            t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
        //此时i=j,交换基准数和a[i]
        t = a[i];
        a[i] = a[index];
        a[index] = t;
        return i;//返回此时基准数所在的索引
    }
}

在这里插入图片描述

其他暂时没搞

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值