内排序算法

内排序算法

每次需要排序的时候总是会忘记基本的排序算法,为了防止自己再次忘记,写个博客加深自己的印象:

简单选择排序

简单选择排序大概就是最简单我们最容易想到的一种排序方法,一共进行n-1次选择,在第i次选择中选择第i小的数放在相应的位置。我们可以想象一种场景,有一些账单需要我们按照时间进行排序,我妈每次选择最早的一张拿在手上,再从剩下的账单里选择最早的放在手中账单的底下。

static class SelectSort{
        static void select_sort(int[] array){
            for(int i=0;i<array.length;i++){
                int min=i;
                for(int j=i+1;j<array.length;j++){
                    if(array[min]>array[j]){
                        min=j;
                    }
                }
                if(min!=i){
                    exchange(array,min,i);//交换min和i
                }
            }
        }
    }

每次选择出一个第i小的数放在正确的位置会发生交换,导致元素位置改变,所以是不稳定的。

插入排序

插入排序我们可以想象我们在玩扑克牌,每次从牌堆中拿一张,根据牌面的大小插入手中的牌。

    static class InsertionSort{
        static void insertion_sort(int[] array){
            for(int j=1;j<array.length;j++){
                int key=array[j];
                int i=j-1;
                while(i>=0&&array[i]>key){
                    array[i+1]=array[i];
                    i--;
                }
                array[i+1]=key;
            }
        }

    }

快速排序

快速排序的重点就在划分,我们选择一个标准元素,然后让它左边的元素都小于它,右边的元素都大于它。接着进行递归处理它左边的所有元素和右边的所有元素。

static class QuickSort{
        static void quick_sort(int[] array,int p,int q){
            if(p<q){
                int r=partition(array,p,q);
                quick_sort(array,p,r-1);
                quick_sort(array,r+1,q);
            }
        }

        static int partition(int[] array,int p,int q){
            int key=array[q];
            int i=p-1;
            for(int j=p;j<q;j++){
                if(array[j]<key){
                    i++;
                    exchange(array,i,j);//交换元素i和j
                }
            }
            exchange(array,++i,q);//交换元素i+1和q
            return i;
        }
    }

在划分的过程中存在交换,因此会打乱相同元素相对顺序。

冒泡排序

每次比较相邻的元素,如果左边的元素比右边的元素大,那么就会交换位置,所以每一轮排序都会把最大的数放在正确的位置。

static class BubbleSort{
        static void bubble_sort(int[] array){
           for(int i=0;i<array.length-1;i++){
               for(int j=0;j<array.length-i-1;j++){
                   if(array[j]>array[j+1]){
                       exchange(array,j,j+1);//交换j和j+1的位置
                   }
               }
           }
        }
    }

归并排序

开始将数组分为长度为1的n个有序表,然后逐步合并。

static class MergeSort{
        static void merge_sort(int[] array,int[] array1){
            int h=1;
            while(h<array.length){
                merge_pass(array,array1,h);
                h=2*h;
                for(int i=0;i<array.length;i++){
                    array[i]=array1[i];
                }
            }
        }

        static void merge_pass(int[] array,int[] array1,int h){
            int i=0;
            while(i<array.length-2*h+1){
                merge(array,array1,i,i+h-1,i+2*h-1);
                i+=2*h;
            }
            if(i<array.length-h+1){
                merge(array,array1,i,i+h-1,array.length-1);
            }else{
                for(;i<array.length;i++){
                    array1[i]=array[i];
                }
            }
        }

        static void merge(int[] array,int[] array1,int a,int b,int c){
            int i=a;
            int j=b+1;
            int k=a;

            while(i<=b&&j<=c){
                if(array[i]<array[j]){
                    array1[k++]=array[i++];
                }else{
                    array1[k++]=array[j++];
                }
            }

            while(i<=b)array1[k++]=array[i++];
            while(j<=c)array1[k++]=array[j++];

        }
    }

希尔排序

对直接插入排序的一种改进,因为基本有序的序列,直接插入最快,记录数很少的无序序列插入也很快。将待排序的记录集分成多个子集,分别对这些子集进行插入排序。

static class ShellSort{
        static void shell_sort(int[] array){
            for(int d=array.length/2;d>=1;d=d/2){
                for(int i=d;i<array.length;i++){
                    if(array[i]<array[i-d]){
                        int key=array[i];
                        int j=i-d;
                        for(;j>=0&&key<array[j];j=j-d){
                            array[j+d]=array[j];
                        }
                        array[j+d]=key;
                    }
                }
            }
        }
    }

堆排序

觉得百度百科写得很清楚了
堆排序

几种排序算法的比较

算法名称稳定性算法复杂度
简单选择排序不稳定O(N^2)
插入排序稳定最坏情况下O(N^2)
快速排序不稳定平均情况O(N*log2(N)),最坏情况O(N^2)
希尔排序不稳定O(N*log2(N))到O(N^2)
冒泡排序稳定最坏情况O(N^2)
归并排序稳定O(N*log2(N))

稳定性是指在排序完成之后相同值的元素的相对位置不会改变*

点赞