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

排序总结(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);
    }

希尔排序的运行结果

希尔排序

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值