排序总结(1)---冒泡排序、选择排序、插入排序、希尔排序

本文深入讲解了冒泡排序、选择排序、插入排序及希尔排序等基本排序算法,并提供了详细的Java实现代码。文中不仅分析了各种排序算法的时间复杂度、空间复杂度及稳定性,还给出了具体的代码实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

排序总结(1)—冒泡排序、选择排序、插入排序、希尔排序

最近温习一下各排序算法,代码块中有详细的注释,test函数在结尾处

先来总结一下排序的时间复杂度、空间复杂度、稳定性


稳定的排序

稳定的排序时间复杂度空间复杂度
冒泡排序最差、平均都是O(n2),最好是O(n)1
双向冒泡排序最差、平均都是O(n2),最好是O(n)1
插入排序最差、平均都是O(n2),最好是O(n)1
归并排序最差、平均、最好都是O(nlogn)O(n)
桶排序O(n)O(k)
基数排序O(dn),d为常数O(n)
二叉树排序O(nlogn)O(n)
图书馆排序O(nlogn),最坏O(n2)O(n)


不稳定排序

不稳定的排序时间复杂度空间复杂度
选择排序最差、平均都是O(n2)1
希尔排序O(nlogn)1
堆排序最差、平均、最好情况都是O(nlogn)1
快速排序平均是O(nlogn),最坏情况是O(n2)O(nlogn)

冒泡排序:

/**
 * @ClassName BublleSort
 * @Description 冒泡排序 最好的时间复杂度:O(n) 最坏的时间的复杂度O(n2) 平均时间复杂度O(n2)
 * 算法为就地排序,是稳定的排序算法
 * @author yj
 */
public class BubbleSort {
    /**
     * 冒泡排序
     * @param source needed sort array
     */
    public static void bubbleSort(int[] source){
        for(int i = 0;i < source.length-1;i++){//循环每一趟排序
                for(int j = 0;j<source.length -i-1;j++){//一趟排序中
                    if(source[j]>source[j+1])swap(source,j,j+1);
                }
        }

    }
    /**
     * 升级的冒泡排序<br>
     * 加入了交换标识的冒泡排序,如果一趟排序中没有发生数据交换说明已经排序完成,
     * 此时交换标识为false,在这一趟排序后提前终止算法
     * @param source
     */
    public static void bubbleSort2(int[] source){
        boolean exchange;//交换标识,如果没有发生交换说明已经排序完成
        for(int i = source.length-1;i>0;i--){//一趟排序
            exchange = false;//每一次排序前设置为false
            for(int j = 0;j<i;j++){
                if(source[j]>source[j+1]){
                    swap(source,j,j+1);
                    exchange = true;//发生交换就设置为true
                }       
            }
            if(!exchange)//没有发生交换,终止
                return ;
        }
    }
    /**
     * swap to number in the array
     * @param source 需要交换的数组数据
     * @param x the index of the number who needed swap in the array
     * @param y 需要交换的数据在source中的位置
     */
    public static void swap(int[] source,int x, int y){
        int temp = source[x];
        source[x] = source[y];
        source[y] = temp;
    }
}

选择排序:

/**
 * 选择排序<br>
 * 平均复杂度为O(n2),不稳定的排序
 * @author hp
 *
 */
public class SelectSort {
    /**
     * 每次循环找出最小值并记录下标index,如果标志位index与i不同,
     * 就将位置为index的数据与位置为i的数据交换
     * @param source
     */
    public static void selectSort(int[] source) {
        int index;// 下标标识,记录未排序序列中最小值
        for (int i = 0; i < source.length - 1; i++) {//每次循环找出最小值并记录下标
            index = i;// 记录未排序的第一个开始位置,进行比较
            for (int j = i + 1; j < source.length; j++) {//循环找出未排序最小值记录到index
                if(source[j]<source[index])index = j;
            }
            if(index != i){//如果标识不等于当前循环未排序的首位,说明有比首位更小的数字,进行交换
                swap(source,i,index);
            }
        }
    }

    /**
     * swap to number in the array
     * 
     * @param source 需要交换的数组数据
     * @param x the index of the number who needed swap in the array
     * @param y 需要交换的数据在source中的位置
     */
    public static void swap(int[] source, int x, int y) {
        int temp = source[x];
        source[x] = source[y];
        source[y] = temp;
    }
}

插入排序:

/**
 * 平均算法复杂度O()n2
 * @author hp
 *
 */
public class InsertSort {
    /**
     * 插入排序
     * @param source
     */
    public static void insertSort(int[] source){
        for(int i = 1;i<source.length;i++){//从第二个元素开始,将其插入到前面合适位置
            for(int j = i;(j>0)&&(source[j]<source[j-1]);j--){//每次向前移动直到到达合适位置
                swap(source,j,j-1);
            }
        }
    }
    /**
     * swap to number in the array
     * 
     * @param source 需要交换的数组数据
     * @param x the index of the number who needed swap in the array
     * @param y 需要交换的数据在source中的位置
     */
    public static void swap(int[] source, int x, int y) {
        int temp = source[x];
        source[x] = source[y];
        source[y] = temp;
    }
}

希尔排序:

为了更清晰体现希尔排序的过程,在算法中插入了打印函数,每次数据交换都能清晰明了

/**
 * 时间复杂度O(nlogn),不稳定排序
 * 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组。
 * 所有距离为d1的倍数的记录放在同一个组中。先在各组内进行直接插入排序;
 * 然后,取第二个增量d2<d1重复上述的分组和排序,
 * 直至所取的增量  =1(  <  …<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
 * @author hp
 *
 */
public class ShellSort {
    public static void shellSort(int[] source){
        int len = source.length;
        for(len = len/2;len!=0;len/=2){//初始时取长度的一半为间隔长度,每次减半直到为0
            for(int i = len;i<source.length;i++){//从每组的第二个位置开始,依次向前插入操作,然后循环到每组的第三个位置。。。
                for(int j = i;(j-len)>=0&&source[j-len]>source[j];j-=len){//插入排序中的核心部分---向前比较、判断条件是否成立并交换
                    swap(source,j-len,j);
                    spy(source);//观察每次交换的情况
                }
            }
        }
    }
    /**
     * 方便观察每次排序的,可以窥探数组排序的情况
     * @param source
     */
    public static void spy(int[] source){
        for(int k = 0;k<source.length;k++){
            System.out.printf("%3s ",source[k]);    
        }
        System.out.println();
    }
    /**
     * swap to number in the array
     * 
     * @param source 需要交换的数组数据
     * @param x the index of the number who needed swap in the array
     * @param y 需要交换的数据在source中的位置
     */
    public static void swap(int[] source, int x, int y) {
        int temp = source[x];
        source[x] = source[y];
        source[y] = temp;
    }
}

测试一下:

public static void main(String[] args) {
        int a[] = {4,2,1,6,3,6,0,-5,1,1};
        System.out.println("排序前:  ");
        for(int i = 0; i < 10; i++){
            System.out.print(a[i]+"  ");
        }
        System.out.println("\n排序后:");
        ShellSort.shellSort(a);
    }

希尔排序的运行结果

希尔排序

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值