排序算法-2

快速排序(QuickSort)
  • 原理
    快速排序用到了分而治之的思想,操作过程是先随机将数组中的一个值暂定为基准值,将数组中大于基准值的数移到基准值右侧,小于基准值的数移至左侧(这一过程其实就是使基准值归位),第一轮基准值归位后,一个数组分为两个数组(不包括基准值),分别对基准值左侧和右侧数据重复基准值归位操作。
  • 过程解析
    以数组arr
    [70,72,26,87,26,80,65,2,66,28,37,8,33,15,55,70,13,83…]为例
    在这里插入图片描述
    为了方便,第一轮选取arr[0]作为base(基准值)。
    利用哨兵i,j, j从右侧往左遍历找到小于等于base的数,停下,然后i从左侧找到 大于或等于的数停下,交换i,j的值,直至i>j, 此时可以完成第一轮基准值归位
动图演示
  • 基准值70 归位
    刚开始 选70作为base值
    i从左侧找,72比70大,停下,此时i=1,j从右侧找,38比70小,停下,此时j=45,交换arr[1] arr[45],也就是交换72和38,
    在这里插入图片描述
    70基准值归位全过程在这里插入图片描述

在这里插入图片描述
现在左侧是比70小的数,右侧是比70大的数。继续以左侧数组为例解释,

  • 19基准值归位
    在这里插入图片描述

在这里插入图片描述

  • 基准值 8归位
    在这里插入图片描述

在这里插入图片描述

  • 基准值4归位
    在这里插入图片描述

在这里插入图片描述

  • 基准值4归位
    在这里插入图片描述

  • 代码实现初版(java)

public static void main(String[] args) {
        Quick_Sort(arr, 0, arr.length - 1);
        for (int i : arr
        ) {
            System.out.println(i);
        }

    }

    public static void Quick_Sort(int[] arr, int begin, int end) {
        if(begin>=end){
            return;
        }
        int tmp = arr[begin];
        int i = begin+1;
        int j = end;
        //基准位归位
        while (i <= j+1) {
            while (i<=j && arr[i] < tmp)
                i++;
            while (i<=j && arr[j] >= tmp )
                j--;

            if (j > i) {
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }
        arr[begin] = arr[j];
        arr[j] = tmp;
        Quick_Sort(arr, begin, j - 1);
        Quick_Sort(arr, j + 1, end);
    }
  • 终版
public static void main(String[] args) {
        Quick_Sort(arr, 0, arr.length - 1);
        for (int i : arr
        ) {
            System.out.println(i);
        }

    }
public static void Quick_Sort(int[] arr, int begin, int end) {
        if(begin<end) {
            int basicIndex = findBasicIndex(arr, begin, end);
            Quick_Sort(arr, begin, basicIndex - 1);
            Quick_Sort(arr, basicIndex + 1, end);
        }
    }
    //基准值归位后的位置
    static int findBasicIndex(int[] arr,int begin,int end){
        int tmp = arr[begin];
        int i = begin+1;
        int j = end;
        while (i<=j) {
            while (i<=j && arr[i] < tmp)
                i++;
            while (i<=j && arr[j] >= tmp )
                j--;

            if (j > i) {
                int t = arr[i];
                arr[i] = arr[j];
                arr[j] = t;
            }
        }
        arr[begin] = arr[j];
        arr[j] = tmp;
        return j;
    }
插入排序(InsertSort)
  • 原理
    插入排序将数组分为有序和无序两部分,依次将无序部分的数据插入到有序数组中。
  • 过程
    1 从数组中第二个元素依次开始抽取元素。
    2 将它和左边的第一个元素比较,大于的话,继续和左边的元素比较,直至遇到比它小的元素,插入到该元素右边
    3 重复上述步骤
代码实现
private static void Insertsort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            // 记录要插入的数据
            int tmp = arr[i];
            // 从已经排序的序列最右边的开始比较,找到比其小的数
            int j = i;
            while (j > 0 && tmp < arr[j - 1]) {
                arr[j] = arr[j - 1];
                j--;
            }
            // 存在比其小的数,插入
            if (j != i) {
                arr[j] = tmp;
            }
        }
    }
希尔排序(ShellSort)
  • 优化过的插入排序,
  • 代码实现
private static void shellsort(int[] arr){
        for (int gap = arr.length/2; gap >0 ; gap /=2) {
            for (int i = gap; i < arr.length; i++) {
                int tmp = arr[i];
                int j=i;
                while(j-gap>=0&&tmp<arr[j-gap]){
                    arr[j] = arr[j-gap];
                    j-=gap;
                }
                // 存在比其小的数,插入
                if (j != i) {
                    arr[j] = tmp;
                }
            }
        }
    }
排序算法比较
排序算法平均时间复杂度平均空间复杂度是否稳定
快速排序O(nlogn)O(nlogn)F
插入排序O(n2)O(1)T
希尔排序O(n1.3)O(1)F
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值