Java中的三个基础排序(冒泡排序,直接插入排序,选择排序)

Java中有很多的排序方法,比如:冒泡排序、快速排序、选择排序、插入排序、希尔排序等很多的排序方法,我们来看一下三个比较基础的关于数组的排序方法:冒泡排序,直接插入排序和选择法排序。

冒泡排序:一次比较两个元素,如果第一个元素比第二个大,那么他们交换位置,依次进行比较相邻的两个元素,从开始的第一个到结尾的最后两个相邻元素的比较完成后,最后一个元素应为该数组中最大的数;然后重复以上步骤(除了确定以后的元素),直到没有元素进行比较的时候,此时的数组已经排序完成。
比如说我现在要比较这么一个数组:

int[] array = {14,16,7,28,99,54,1,10};

那么它所实现的过程是如何呢?我以画图的形式表达出来:
第一趟的比较,确定了最大数99
第一趟的比较,确定了最大数99

第二趟的比较,确定了最大数54和99
第二趟的比较,确定了最大数54和99

第三趟的比较,确定了最大数28,54和99
第三趟的比较,确定了最大数28,54和99

第四趟的比较,确定了最大数16,28,54和99
第四趟的比较,确定了最大数16,28,54和99

第五趟的比较,确定了最大数14,16,28,54和99
第五趟的比较,确定了最大数14,16,28,54和99

第六趟的比较,确定了最大数10,14,16,28,54和99
第六趟的比较,确定了最大数10,14,16,28,54和99

最后一趟则排序完成,那么我们如果想用代码实现该排序方法,应该怎么实现?
此时我们需要两个for循环,外循环控制该数组排序的趟数
内循环控制每一趟排序的次数

/**
 * 冒泡排序
 * @author 王瑜
 *冒泡排序的实现
 */
public class WangYu {
    public static void show(int[] array){//遍历数组
        for(int k = 0;k < array.length;k++){
            System.out.print(array[k]+ "   ");
        }
    }
    public static void bubbleSort(int[] array){
        int tmp = 0;//定义一个中间变量
        for(int i = 0;i < array.length;i++){//外层循环控制排序的趟数
            for(int j = 0; j < array.length -1 -i;j++){//内层循环控制每一趟排序的次数
                if(array[j] > array[j+1]){//如果前一个数比后一个数大,则交换位置用中间变量
                tmp = array[j];
                array[j] = array[j+1];
                array[j+1] = tmp;
                }
            }
        }
    }
    public static void main(String[] args) {//利用写的功能函数进行测试
        int[] array = {14,16,7,28,99,54,1,10};
        bubbleSort(array);
        show(array);
    }
}

输出为:

1   7   10   14   16   28   54   99

如上所示,这就是冒泡排序的思想及实现方法
那么冒泡排序是否稳定呢?
理所当然是稳定的,因为它是相邻的两个元素依次进行比较,从未有跳跃的比较,所以肯定是稳定的
它的时间复杂度是多少呢?
是O(n^2)

看完了冒泡排序,我们再来看另一个基础排序的方法:直接插入排序
直接插入排序是什么呢?像我们玩扑克牌一样,接起的第一张牌是已经确定的一张(即是有序的),后面再接上来的牌跟第一张牌比较,确定第二张的顺序,依次类推;
即将数组中后面无序的元素提出来,跟已经有序的前面的元素进行依次比较,插入到该有序元素中,保证了依然有序,当所有元素插入完毕,则完成排序。
想要实现本方法呢,需要定义一个中间变量,中间变量的值为无序元素中提取出来的元素,然后将有序的最后(右)一个元素与该元素比较,依次向前比较,保证插入后有序即可
若我想将这么一组元素实现排序(使用直接插入排序),则方法如图
直接插入排序

int[] array = {13,52,36,77,55,1,22,3,7};

i为1号下标,且j为i-1的下标,先将i位置的数存储在tmp中间变量中,如果i位置的数的值大于j位置的数的值,则将现在j位置的值赋值给i所在的值,执行j–;继续让前面有序的值跟tmp(也就是原本无序中的值进行比较)如果大于则和以上执行相同步骤,小于的话则跳出循环,并将tmp的值赋值给所空位置,完成排序
第一趟比较:{13,52,36,77,55,1,22,3,7 }
第二趟比较:{13,36,52,77,55,1,22,3,7}
第三趟比较:{13,35,52,77,55,1,22,3,7}
第四趟比较:{13,35,52,55,77,1,22,3,7}
第五趟比较:{1,13,35,52,55,77,22,3,7}
第六趟比较:{1,13,22,35,52,55,77,3,7}
第七趟比较:{1,3,13,22,35,52,55,77,7}
第八趟比较:{1,3,7,13,22,35,52,55,77}
粗体为确定的有序序列;

那我们来看一下如何可以实现该排序呢?上代码:

/**
 * 直接插入排序
 * @author 王瑜
 *InsertSort
 */
public class WangYu {//遍历数组
    public static void show(int[] array){
        for(int k = 0;k < array.length;k++){
            System.out.print(array[k]+ "   ");
        }
    }
    public static void InsertSort(int[] array){//直接插入排序的方法
        int j;
        for(int i = 1;i < array.length;i++){从数组的第二个元素开始提取向前比较插入
            int tmp = array[i];
            for(j = i - 1; j >= 0;j--){
                if(tmp < array[j]){//如果插入的元素小于有序的最后一个元素,则j位置的元素后移
                    array[j + 1] = array[j];

                }
                else{
                    break;
                }
            }
            array[j + 1] = tmp;
        }
    }
    public static void main(String[] args) {
        int[] array = {13,52,36,77,55,1,22,3,7};
        InsertSort(array);
        show(array);
    }
}

输出为:

1   3   7   13   22   36   52   55   77 

稳定性:直接插入排序没有跳跃排序,所以其是稳定的
时间复杂度:O(n^2)

那么我们再看最后一个基础排序————>选择法排序
选择法排序是如何实现的呢?
将指定排序位置与其他数组元素进行对比,如果满足条件就交换元素值,(把满足条件的元素与指定的排序位置交换)
每一趟从未排序的数据元素中取出最小(或最大)的一个元素,顺序地放在已经排好序的数列的最后,直到全部待排序的元素排序完毕
也就是从0索引开始,依次和后面元素比较,小的往前放,第一次完毕,最小值出现在了最小索引处
也就是假设有这么一个数组

int[] array = {20,11,13,10};

从20开始向后比较,20比11大,所以交换位置成了{11,20,13,10} 此时的11要继续和13,10比较,就会变成{10,20,13,11}
那么如果我想要排序这个数组

int[] array = {23,55,17,10,25,66,99};

该如何实现呢?

/**
 * 选择排序
 * @author 王瑜
 *SelectSort
 */
public class WangYu {
    public static void show(int[] array){
        for(int k = 0;k < array.length;k++){
            System.out.print(array[k]+ "   ");
        }
    }
    public static void SelectSort(int[] array){
        int tmp = 0;
        int minIndex = 0;
        for(int i = 0;i < array.length;i++){
            minIndex = i;
            for(int j = i + 1;j < array.length;j++){
            if(array[minIndex] > array[j]){
                tmp = array[minIndex];
                array[minIndex] = array[j];
                array[j] = tmp;
            }
            }
        }

    }
    public static void main(String[] args) {
        int[] array = {23,55,17,10,25,66,99};
        SelectSort(array);
        show(array);
    }
}

输出为:

10   17   23   25   55   66   99 

稳定性:因为有跳跃的比较,所以是不稳定的
时间复杂度:O(n^2)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值