考研篇——排序算法总结

目录

插入排序

直接插入排序

折半插入排序

希尔排序

交换排序

冒泡排序

快速排序

选择排序

简单选择排序

堆排序

归并排序和基数排序

归并排序

基数排序

各排序算法比较

性质比较

插入排序
  • 直接插入排序

  • 折半插入排序

  • 希尔排序

直接插入排序
  1. 算法理解

    • 算法思想

      • 每次将一个待排序的记录安其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成

      • 算法图解

        在这里插入图片描述

  2. 代码实现

    void InsertSort (int A[], int n) {
        int temp=A[0];
        for (int i=1; i<n; i++) {   //将各元素插入已安排好的序列中
            if (A[i]<A[i-1]) {      //若A[i]关键字小于前驱
                temp=A[i];          //用temp暂存A[i]
                for(int j=i-1; j>0 && A[j]>temp; j--) { //检查所有前面已排好序的元素
                    A[j+1]=A[j];    //所有大于temp的元素都向后挪位
                }
                A[j+1]=temp;        //复制到插入位置
            }
        }
    }
  3. 性能分析

    • 空间复杂度:O(1)

    • 时间复杂度

      • 最好情况:表中元素已经有序,此时每插入一个元素,都只序比较一次而不用移动元素。O(n)

      • 最坏情况:表中元素顺序刚好与排序结果中的元素顺序相反(逆序),总的比较次数达到最大,总的移动次数也达到最大。O(n²)

      • 平均时间复杂度:O(n²)

    • 稳定性:由于每次插入元素时总是从后向前比较再移动,所以不会出现相同元素相对位置发生变化的情况。(稳定)

    • 适用性:顺序存储和链式存储的线性表

折半插入排序
  1. 算法理解

    • 算法思想:先用折半查找找到应该插入的位置,再统一移动带插入元素之后的所有元素,改进的是比较次数,移动次数并未改变。

    • 算法图解

  2. 代码实现

    void InsertSort (int A[], int n) {
        int low, high, mid;
        for (int i=2; i<=n; i++) {  //依次将A[2]~A[n]插入前面的已排序序列
            A[0]=A[i];              //将A[i]暂存到A[0](哨兵)
            low=1;                  //设置折半查找的范围
            high=i-1;
            while (low<=high) {     //折半查找(默认递增有序)
                mid=(low+high)/2;   //取中间点
                if (A[mid]>A[0]) {  //查找左半子表
                    high=mid-1;
                } else {            //查找右半子表
                    low=mid+1;
                }
                for (int j=i-1; j>=high+1; j--) { //统一后移元素,空出插入位置
                    A[j+1]=A[j];
                }
                A[high+1]=A[0];     //插入操作
            }
        }
    }
    //当low>high时,折半查找停止,应将[low,i-1]内的元素全部右移,并将A[0]复制到low所指位置
    //当A[mid]==A[0]时,为保证算法的“稳定性”,应继续在mid所指位置右边寻找插入位置
  3. 性能分析

    • 比起“直接插入排序”,比较关键字的次数减少了,但是移动元素的次数没变,整体看来时间复杂度仍然是O(n²)

    • 稳定性:稳定

    • 适用性:只适用于顺序表

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值