• 面试基础题【2】--排序算法


    ----接上

    面试基础题【1】--排序算法_追求决定高度的博客-CSDN博客

    1.4 ----shellSort

    排序算法        平均时间复杂度        最好情况        最坏情况        空间复杂度        稳定性

    希尔排序        O(nlogn)                 O(nlog^2 n)      O(nlog^2 n)        O(1)               不稳定

     排序思路:基于简单的插入排序的改进,也叫缩小增量排序

    简单插入排序问题:当插入的数较小,左有序表元素与插入的值比较的次数增多以及左表元素后移的次数增多效率较低

    1. void shellSort(vector<int>& nums) {
    2. for (int gap = nums.size() / 2; gap > 0; gap /= 2){//分组递减
    3. //增量为gap 的两个数进行对比 例如:nums[0]--nums[gap]
    4. //令最大下标的数下标为 gap,保证 每一个都能比较完
    5. for (int i = gap; i < nums.size(); i++){
    6. for (int j = i - gap; j >= 0; j -= gap) {
    7. if (nums[j] > nums[j+gap]) {
    8. int t = nums[j];
    9. nums[j] = nums[j+gap];
    10. nums[j+gap] = t;
    11. }
    12. }
    13. }
    14. }
    15. return nums;
    16. }

    1.5 ----mergeSort

    排序算法        平均时间复杂度        最好情况        最坏情况        空间复杂度        稳定性

    归并排序        O(nlogn)                 O(nlog n)      O(nlog n)        O(n)                      稳定

    排序思想:采用分治法的思想,将大问题划分为小问题进行递归求解-分而治之

     

    代码:

    1. void merge(vector<int>& nums, int left, int mid, int right) {
    2. int i = left; int j = mid+1; int t = 0;
    3. vector<int>temp(nums.size(),0);
    4. while (i <= mid && j <= right)
    5. {
    6. if (nums[i] <= nums[j])temp[t++] = nums[i++];
    7. else temp[t++] = nums[j++];
    8. }
    9. while (i <= mid)temp[t++] = nums[i++];//左边序列剩元素
    10. while(j<=right)temp[t++] = nums[j++];//右边剩元素
    11. for (int i = 0; i < right-left+1; i++) { //小区间合并->大区间合并
    12. nums[i + left] = temp[i];
    13. }
    14. }
    15. void mergeSort(vector<int>& nums,int left,int right) {
    16. //拆到一个区间只有一个元素时结束
    17. if (left < right) {
    18. int mid = (left + right) / 2;
    19. mergeSort(nums, left, mid);//左边区间一直拆
    20. mergeSort(nums, mid + 1, right);//右边区间一直拆
    21. merge(nums, left, mid, right);
    22. //拆完开始一个一个合并
    23. //先比较并合并左边/右边
    24. }
    25. }

    1.5 ----quickSort

    排序算法        平均时间复杂度        最好情况        最坏情况        空间复杂度        稳定性

    快速排序        O(nlogn)                 O(nlog n)           O(n^2)          O(logn)               不稳定

    排序思想:分治法+填坑【递归思想】

    与“归并”不同的是,快排的分区是按照基准值进行分区的,将比基准值小的分在左边, 比基准值大的分在右边。

    代码:

    1. void quickSort(vector<int>& nums, int left, int right) {
    2. int start = left; int end = right;
    3. if (start >= right)return;//递归结束条件
    4. int baseValue = nums[start];//设定一个基准值,用baseValue接收,防止start元素被替换
    5. while (start != end){//只要起始与终点不同 就执行
    6. while (nums[end] >= baseValue && end > start) {//比较终值与基准值的大小,如果大,就--,起始下标指向 end
    7. end--;
    8. }
    9. if (nums[end] < baseValue)swap(nums[start], nums[end]);//如果小,就交换
    10. while (nums[start] <= baseValue && end > start) {//此时指针指向了start,比较start开始的值与基准值的大小,如果小就++
    11. start++;
    12. }
    13. if (nums[start] > baseValue)swap(nums[start], nums[end]);//如果大,就交换,指针再次回到end
    14. }
    15. //第一轮比较结束,此时基准值的位置为 start=end;
    16. quickSort(nums, left , start-1);//基准值的右侧区间进行比较
    17. quickSort(nums, start+1 , right);//基准值的左侧区间进行比较
    18. }

  • 相关阅读:
    例解什么是Python装饰器
    GJB软件需求规格说明-编制指南
    操作系统笔记——Linux实战、Windows(持续更新)
    嵌入式软件开发常用的3种架构
    计算机网络与技术——物理层
    Spring之Bean生命周期之二--- Instantiation阶段
    LeetCode 33. 搜索旋转排序数组
    Spring Security加密和匹配
    Verilog 不同编码风格对综合电路的影响
    GPPT阅读笔记
  • 原文地址:https://blog.csdn.net/qq_57328462/article/details/125497151