常见排序算法

排序算法

1、插入排序

1-1直接插入排序

->思想:把待排序的数据按其值的大小插入到已经排好序的有序数组中,直到所有数据插完为止,即可得到一个有序数列。

->时间复杂度:最坏情况下:O(N^2) ->数据逆序时

最好情况下:O(N) ->数据有序时

->稳定排序

->使用场景:数据越有序越快,适用于趋于有序的数组

1-2希尔排序【也称:缩小增量排序】

->思想:先选定一个整数n【增量】,把待排序的数据分成n个组,这些数据中所有距离为n的为一组,组内进行插入排序;然后缩小增量【n变小】,继续上述操作,直至n为1,就可排好数据。

->希尔排序是对直接插入排序的优化;当增量>1时,相当于是预排序。

->gap的取值方法很多,导致很难去计算,因此在一些资料中给出的希尔排序的时间复杂度不固定

暂时的时间复杂度:O(N^1.3 ~N^1.5)

->不稳定排序

2、选择排序

2-1 直接选择排序

->思想:每次从待排的数据中选择出一个最小(降序,就选最大)的元素,放到序列的起始位置,直至所有数据被排完。

每次只排一个。

直接选择排序的进阶:

每次排两个。思想:与直接选择排序类似,假设要升序的数据,每次从待排的数据中选择出一个最小的元素放到序列的起始位置,同时选择一个最大的元素放于末位置,直至所有数据被排完。

实现如下:

上面标※的内容,是考虑到最大值就在left位置时,此时要将找到的最小值与其进行交换,会导致最大值就跑到了交换后最小值的位置,因此需要修正一下。

2-2堆排序

降序:建立小根堆

升序:建立大根堆;每次让最后一个数据与堆顶元素进行交换;交换完之后向下调整;直到所有数据交换完成

->堆排序的时间复杂度:O(NlogN)

->空间复杂度:O(1)

->不稳定的排序

3、交换排序

3-1 冒泡排序

i表示趟数,每次排一个;

j每次交换找到最大的/最小的

->没优化的时间复杂度:O(N^2)

->优化后的时间复杂度:O(N)

->稳定的排序

3-2 快速排序

思想

主框架如下图:让待排序元素的某个值作为基准值,将序列按照该基准值分为两个部分,左边是小于它的,右边是大于它的;然后左右子序列重复这个过程;直到该序列排好序即可。

针对每种与基准值交换的方法【分割成两个序列的方法不同】:

法1:hoare

->最坏情况:顺序时,O(N^2)

->时间复杂度:理想情况,O(NlogN)

->使用场景:无序的情况。在有序的情况时,容易栈溢出。【递归】

法2:挖坑法

把第一个位置挖出来作为基准值,第一个位置就为坑了;从后头开始,将小于基准值的放到坑中,此时,该位置为新的坑;在从左边开始,将大于基准值的放到新坑中,此刻这个位置就是新的坑,以此类推。

->快排时间复杂度:理想情况下O(NlogN);有序或者逆序时O(N^2)

->快排空间复杂度:最好O(N);最坏:O(N),当N足够大时,递归的深度就大。

解决方案【让序列尽可能均匀分割】:

1、随机选取基准法

2、三数取中法【找前中后三个位置的数,进行比较,把第二大的数作为基准】

针对有序的数据:

如果待排数据较少时,可以采用直接插入排序。

->快速排序不稳定。

非递归实现快速排序:

public static void quickSort2(int[] array){
        Stack<Integer> stack = new Stack<>();
        int left = 0;
        int right = array.length-1;
        int pivot = patrition(array,left,right);

        //前边超过一个数字了就入栈
        if (pivot > left+1){
            stack.push(left);
            stack.push(pivot-1);
        }

        if (pivot < right-1){
            stack.push(pivot+1);
            stack.push(right);
        }

        while (!stack.isEmpty()){
            right = stack.pop();
            left = stack.pop();
            pivot = patrition(array,left,right);

            if (pivot > left+1){
                stack.push(left);
                stack.push(pivot-1);
            }

            if (pivot < right-1){
                stack.push(pivot+1);
                stack.push(right);
            }
        }


    }

4、归并排序

先分解,再合并。

->不论什么数组,时间复杂度:O(NlogN)

->空间复杂度:O(N)

->稳定的排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值