数据结构-排序

本文详细介绍了三种常见的排序算法:插入排序、快速排序和希尔排序。插入排序在最好情况下的时间复杂度为O(N),而快速排序平均时间复杂度为O(N*logN)。希尔排序是对插入排序的优化,平均时间复杂度约为O(N^1.3)。三种算法的空间复杂度均为O(1)。通过理解这些排序算法的工作原理,可以更好地选择适合不同场景的排序方法。
摘要由CSDN通过智能技术生成

1.插入排序

时间复杂度:最坏情况下为O(N*N),此时待排序列为逆序,或者说接近逆序
      最好情况下为O(N),此时待排序列为升序,或者说接近升序

空间复杂度:O(1)

    public void insertSort (int[] a) {
        int sentinel;   //哨兵,用来记录可能会因移动数组而覆盖掉的数
        int j;  //已排好序的数组的最大下表
        for (int i = 1; i < a.length; i++){
            sentinel = a[i];    //记录当前数
            j = i - 1;  //i前面的数都是已经排好序的,第一轮时,j=0,默认第一个a[0]已经排好
            //移动前面排好的数组,找到比哨兵小的第一个数
            //j是0-j都比哨兵大而结束循环,j = -1
            while (j >= 0 && sentinel < a[j]){
                a[j + 1] = a[j];    //向后移动排好序的数组
                j--;
            }
            a[j + 1] = sentinel;    //a[j]是比哨兵小的第一个数,因此j+1才是哨兵插入的位置
        }
    }

2.快速排序

时间复杂度:O(N*logN)

空间复杂度:O(N)

    public void quickSort(int[] arr, int low, int high) {
        // 终止条件,高低指针重合或相反
        if (low >= high) return;
        // 哨兵划分操作(以 arr[low] 作为基准数),哨兵,将所有比哨兵小的移到左边,比哨兵大的移到右边
        int i = low, j = high;
        while (i < j) {
            while (i < j && arr[j] >= arr[low]) j--;    //找到比哨兵小的high位
            while (i < j && arr[i] <= arr[low]) i++;    //找到比哨兵大的low位
            swap(arr, i, j);                            //将大的交换到右边,小的交换到左边,注意,哨兵位置在0,并没有交换
        }
        swap(arr, i, low);  //将哨兵移动到i位上,执行完此行,完成真正的划分,哨兵左边为小,右边为大
        // 递归左(右)子数组执行哨兵划分
        quickSort(arr, low, i - 1); //因为哨兵已经将小的移到左边,大的移到右边,因此无需传哨兵位置
        quickSort(arr, i + 1, high);
    }

    public void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

3.希尔排序 - 插入排序增强版

时间复杂度平均:O(N^1.3)
空间复杂度:O(1)

public void ShellSort(int[] arr) {
        int interval = arr.length / 2; //每次对gap折半操作,将间隔为gap的元素视为一组
        while (interval >= 1) {
            //对每组插入排序
            for (int i = interval; i < arr.length; i++){//每个i对应的组,对i及左边同一组的元素进行插入排序
                int sentinel = arr[i];  //哨兵
                int j = i - interval;
                while (j >= interval - 1 && sentinel < arr[j]){
                    arr[j + interval] = arr[j];
                    j = j - interval;
                }
                arr[j + interval] = sentinel;
            }
        }
    }

4.选择排序

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值