十大排序算法

Posted cmg219

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十大排序算法相关的知识,希望对你有一定的参考价值。

今天学习了下排序算法,参照别人的思路,自己实现了一次。此文作为今天学习的总结,以便以后复习查看。这篇博客中所提到的所有排序算法均以从小到大排序为例,其他情况请自行类比。

一.基本概念

1.算法分类

技术图片

2.算法复杂度比较

技术图片

二.各种算法实现及思路

1.冒泡排序

1.1算法描述

1)比较相邻的元素。如果前一个比后一个大,就交换它们两个;
2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;
3)针对所有的元素重复以上的步骤,除了最后一个;
4)重复步骤1~3,直到排序完成。为了优化算法,可以设立一个布尔标识,每趟排序开始前设为false,如果该趟排序发生了交换就置为true,如果一趟排序结束标识仍为false表示该趟排序没有发生交换,即数组已经有序,可以提前结束排序。

1.2算法实现

//冒泡排序
    public static void bubbleSort(int[]array){
        int length=array.length;
        boolean flag;//标志位
        for(int i=0;i<length;i++){
            /*设置标识,判断这趟排序是否发生了交换。
         如果未发生交换,则说明数组已经有序,不必再排序了*/
            flag=true;
            for(int j=0;j<length-i-1;j++){
                if(array[j]>array[j+1]){
                    swap(array,j,j+1);
                    flag=false;
                }
            }
            if(flag==true)
                break;
        }
    }
    private static void swap(int[]array,int i,int j){
        int temp=array[i];
        array[i]=array[j];
        array[j]=temp;
    }

1.3鸡尾酒算法

鸡尾酒算法是对冒泡算法的改进,将大的数往后冒泡,小的数往前冒泡

//鸡尾酒排序
    //冒泡的改进,最大的往后面冒泡的同时最小的往前面冒泡
    public static void cocktailSort(int[] array) {
        int left=0;
        int right=array.length-1;
        while(left<right){
            //最大的往后面冒泡
            for(int i=left;i<right;i++){
                if(array[i]>array[i+1]){
                    swap(array,i,i+1);
                }
            }
            right--;
            //最小的往前面冒泡
            for(int i=right;i>left;i--){
                if(array[i]<array[i-1]){
                    swap(array,i,i-1);
                }
            }
            left++;
        }
    }

2.快速选择排序

2.1算法描述

1)遍历一次数组,找到最小值与数组首元素交换,这时候数组首元素为排序区,后面为非排序区
2)找到非排序区的最小值,放在排序区后
3)重复2)步骤,直到非排序区为空

2.2算法实现

//简单选择排序
    //每次遍历把最小的插入到前面
    public static void selectionSort(int[] array) {
        int length=array.length;
        for(int i=0;i<length;i++){
            int minIndex=i;//用于保存最小索引
            for(int j=i;j<length;j++){
                if(array[j]<array[minIndex]){
                    minIndex=j;
                }
            }
            swap(array,i,minIndex);
        }
    }

3.直接插入排序

3.1算法描述

直接插入排序算法有点像摸扑克牌,手牌是已经排好序的,这时候从牌组里摸一张牌,比较摸牌和手牌的大小,然后插入牌。
1)从第一个元素开始,该元素可以认为已经被排序;
2)取出下一个元素,在已经排序的元素序列中从后向前扫描;
3)如果该元素(已排序)大于新元素,将该元素移到下一位置;
4)重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
5)将新元素插入到该位置后;
6)重复步骤2~5

3.2算法实现

//直接插入排序
    //是对排序好的数组进行排序,即把数字插入排序好的数组
    public static void insertionSort(int[] array) {
        int length=array.length;
        for(int i=1;i<length;i++){
            int current=array[i];
            int prevIndex=i-1;
            while(prevIndex>=0&&current<array[prevIndex]){
                //把array[prevIndex]后移一位
                array[prevIndex+1]=array[prevIndex];
                prevIndex=prevIndex-1;
            }
            array[prevIndex+1]=current;
        }
    }

4.希尔排序

4.1算法描述

希尔排序是直接插入排序的改进,也可以说直接插入排序是希尔排序的特例,将gap设为1就是上面的实现直接排序。先将整个待排元素序列分割成 gap 个增量为 gap 的子序列(每个子序列由位置相差为 gap 的元素组成,整个序列正好分割成 gap 个子序列,每个序列中有 n / gap 个元素)分别进行直接插入排序,然后缩减增量为之前的一半再进行排序,待 gap == 1时,希尔排序就变成了直接插入排序。因为此时序列已经基本有序,直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的。gap初始值一般取 len / 2。

4.2算法实现

//希尔排序
    //直接插入排序的改进版
    public static void ShellSort(int[] array) {
        int length=array.length;
        int gap=length/2;

        while(gap>0){
            for(int i=gap;i<length;i++){
                int prevIndex=i-gap;
                int current=array[i];
                while(prevIndex>=0&&current<array[prevIndex]){
                    array[prevIndex+gap]=array[prevIndex];
                    prevIndex=prevIndex-gap;
                }
                array[prevIndex+gap]=current;
            }
            gap=gap/2;
        }
    }

以上是关于十大排序算法的主要内容,如果未能解决你的问题,请参考以下文章

十大经典排序算法总结(桶排序)

十大经典排序算法总结(希尔排序)

十大经典排序算法总结(快速排序)

十大经典排序算法总结(冒泡排序)

十大经典排序算法总结(堆排序)

十大经典排序算法的算法描述和代码实现