leetcode排序算法总结—时间复杂度o(nlogn)-希尔/堆排/快排/归并小记

2023-11-17

排序算法总结—时间复杂度O(nlogn)—希尔/堆排序/快排/归并

在这里插入图片描述

希尔排序

有一段间隔的排序,可以逐个子表进行排序,然(例如王道)都给出便于计算机进行连续访问的程序算法,即依次按元素比较不同子表进行子表的调整。

  • 时间复杂度O(n^1.3) 最坏情况下n方
  • 空间复杂度O(1)
  • 不稳定
  • 适用于线性表为顺序存储。

数组排序例题:给你一个整数数组nums,请你将该数组升序排列。

/*** Note: The returned array must be malloced, assume caller calls free().
 */
//希尔
int* sortArray(int* nums, int numsSize, int* returnSize){
    // int *returns = (int *)malloc(sizeof(int )* numsSize);
    int temp,index;//暂存当前比较的数组元素
    for(int dk = numsSize/2;dk > 0;dk /= 2)
    {
        // printf("%d ",dk);
        for(int i = dk;i < numsSize;i++)
        {
            // printf("%d",nums[i-dk]);
            if(nums[i] < nums[i-dk])
            {
                temp = nums[i];
                index = i-dk;
                while(index >= 0 && temp < nums[index])
                {
                    // printf("%d ",index);
                    nums[index+dk] = nums[index];
                    index -= dk;
                }
                nums[index+dk] = temp;
                // printf("%d",nums[index+dk]);
            }
        }
    }
    // for(int k = 0;k < numsSize;k++)
    // {
    //     returns[k] = nums[k];
    // }
    *returnSize = numsSize;
    return nums;
}

相对名次例题
给出N名运动员的成绩,找出他们的相对名次并授予前三名对应的奖牌。前三名运动员将会被分别授予 “金牌”,“银牌” 和“ 铜牌”(“Gold Medal”, “Silver Medal”, “Bronze Medal”)。
(注:分数越高的选手,排名越靠前。)
`示例 1:
输入: [5, 4, 3, 2, 1]
输出: [“Gold Medal”, “Silver Medal”, “Bronze Medal”, “4”, “5”]
解释: 前三名运动员的成绩为前三高的,因此将会分别被授予 “金牌”,“银牌”和“铜牌” (“Gold Medal”, “Silver Medal” and “Bronze Medal”).
余下的两名运动员,我们只需要通过他们的成绩计算将其相对名次即可。
提示:
1.N 是一个正整数并且不会超过 10000。
2.所有运动员的成绩都不相同。

/*** Note: The returned array must be malloced, assume caller calls free().***/
char ** findRelativeRanks(int* score, int scoreSize, int* returnSize){
    *returnSize = scoreSize;
    int a[scoreSize];
    for(int m = 0;m < scoreSize;m++)
    {
        a[m] = score[m];
    }
    char **returns = (char **)malloc(sizeof(char*)*scoreSize);
    int temp,index;
    for(int dk = scoreSize/2;dk > 0;dk /= 2)
    {
        for(int i = dk;i < scoreSize;i++)
        {
            if(score[i-dk] < score[i])
            {
                temp = score[i];
                index = i-dk;
                while(index >= 0 && temp > score[index])
                {
                    score[index+dk] = score[index];
                    index -= dk;
                }
                score[index+dk] = temp;
            }
        }
    }
    // printf("%c",(char)(5+'0'));
    for(int k = 0;k < scoreSize;k++)
    {
        for(int m = 0;m < scoreSize;m++)
        {
            if(a[k] == score[m])
            {
                if(m == 0)
                    returns[k] = "Gold Medal";
                else if(m == 1)
                    returns[k] = "Silver Medal";
                else if(m == 2)
                    returns[k] = "Bronze Medal";
                else
                {
                    returns[k] = (char*)malloc(sizeof(char)*10);
                    sprintf(returns[k],"%d",m+1) ;
            
            // char m = (k+'0');
            // returns[k] = m;
                }
                break;
            }
        }
        
            
    }
    return returns;
}

堆排序

适合关键字超级多的情况。比如一万个数挑出前100个最大最小值。
在这里插入图片描述
在建立大根堆或小根堆情况下,递归排序,提出根结点,继续建立大根堆或小根堆。

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
  • 不稳定

最小的k个数
输入整数数组arr,找出其中最小的k个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。**

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
//堆排序

void heapAdjust(int a[],int k,int len)
{
    int temp = a[k];
    for(int j = k*2 ;j <= len;j *= 2)//第2个结点-1 = 下标
    {
        if(j < len && a[j] > a[j+1])
        {
            j++;
        }
        if(a[j] >= temp) 
            break;
        else
        {
            a[k] = a[j];
            k = j;
        }
    }
    a[k] = temp;
}
void buildheap(int a[],int len)
{
    for(int j = len/2;j > 0;j--)
    {
        heapAdjust(a,j,len);
    }
}
void swap(int *a,int *b)
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
int* getLeastNumbers(int* arr, int arrSize, int k, int* returnSize){
    // int * a = (int *)malloc(sizeof(int )*(arrSize+1));
    int a[arrSize+1];
    
    // arr[arrSize] = (int *)malloc(sizeof(int )*1);
    // arr[arrSize] = 1;
    // printf("%d",arr[arrSize]);
    
    int m = 1;
    for(int j = 0;j < arrSize;j++)
    {
        
        a[m++] = arr[j];
        // printf("%d",a[m-1]);
    }
    *returnSize = k;
    int *returns = (int *)malloc(sizeof(int) * k);
    buildheap(a,arrSize);
    for(int i = 0,x = arrSize;i < k;i++,x--)
    {
        returns[i] = a[1];
        // printf("%d",a[1]);
        // printf("%d ",a[x]);
        swap(&a[1],&a[x]);
        // printf("%d",a[1]);
        // printf("%d ",a[x]);
        heapAdjust(a,1,x-1);
        // printf("m%dm",returns[i]);
    }
    return returns;
}

快速排序

以某一个元素为枢轴,以轴旋转,比轴小的在左侧,比轴大的在右侧。
每次排序会有一个位置元素回到确定的位置。(理想下,第k轮,排好2的k-1次方个数)
该代码重要的是分区思想的代码,注意边界条件。
1⃣️最简单的思路是:从 left 开始,遇到比基数大的数,就交换到数组最后,并将 right 减一,直到 left 和 right 相遇,此时数组就被分成了左右两个区域。再将基数和中间的数交换,返回中间值的下标即可。
2⃣️双指针:从 left 开始,遇到比基数大的数,记录其下标;再从 right 往前遍历,找到第一个比基数小的数,记录其下标;然后交换这两个数。继续遍历,直到 left 和 right 相遇。然后就和刚才的算法一样了,交换基数和中间值,并返回中间值的下标。
(我猜我们会考双轴快排)

  • 时间复杂度:O(nlogn)
  • 空间复杂度:最好情况O(logn) 有递归存在,栈的深度为logn
  • 不稳定
    还是用排序数组的题
    这个敲的很顺手!
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* sortArray(int* nums, int numsSize, int* returnSize){
    if(numsSize == 0) return nums;
    *returnSize = numsSize;
    quicksort(nums,0,numsSize-1);
    return nums;
}
void quicksort(int a[],int start,int end)
{
    if(start >= end) return;
    int mid = partition(a,start,end);
    quicksort(a,start,mid-1);
    quicksort(a,mid+1,end);
}
int partition(int a[],int start,int end)
{
    int temp = a[start];
    int left = start + 1;
    int right = end;
    while(left < right)
    {
        while(left < right && a[left] <= temp) left++;
        // while(left < right && a[right] >= temp) right--;
        if(left != right)
        {
            swap(a,left,right);
            // left++;
            right--;
        }
    }
    if(left == right && a[right] > temp) right--;
    if(right != start) swap(a,start,right);
    return right;
}
void swap(int a[],int x,int y)
{
    int t = a[x];
    a[x] = a[y];
    a[y] = t;
}

归并排序

两个有序子表合并,整个归并排序需要进行logn向上取整趟。
先拆开,再两两合并。
在这里插入图片描述

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(n)需要一个辅助数组的空间
  • 稳定!!终于稳定啦!撒花
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

leetcode排序算法总结—时间复杂度o(nlogn)-希尔/堆排/快排/归并小记 的相关文章

  • UE44如何使用Geometry(BSP)笔刷,快速创建游戏原型?

    游戏原型搭建 如何快速搭建场景 一 好处1 防止同时也放大了对应的网格 如果像unity里面一样 R放大缩小以后 网格也会对应拉伸 失真 导致了材质会被拉伸或者缩小 1 选择Geometry 在BrushSetting里面 将X Y Z对应
  • ubuntu 20.04 安装 pycharm 2022.1 .3 及其卸载

    下载 官网下载 https www jetbrains com pycharm 安装 下载好的文件显示如下 打开终端 进入你刚下载的文件所在的文件夹目录 例如我的放在Downloads这个文件夹 cd Downloads 查看文件夹里的文件

随机推荐

  • ROS navigation分析:navigation框架

    前言 ROS navigation stack是ROS提供的一个非常重要且常用的模块 它的主要作用是实现机器人的定位 导航和避障功能 在ROS wiki上 Maintainer把它的功能归纳为 It takes in information
  • 从零实现DevOps(五):Jenkins+SSH远程部署SpringBoot项目

    上篇文章 我从安装Jenkins插件开始 给大家讲解了如何从Jenkis本地环境中 以启动jar包脚本的方式部署SpringBoot项目 但是呢 以咱们日常的开发来说 所有服务都部署在一台服务器上根本就不是一个合理的方案 更不可能在所有服务
  • 基于FPGA的一维卷积神经网络CNN的实现(五)数据量化(附代码)

    数据量化 环境 Pytorch Pycham Matlab 订阅后有问题 或者需要该节的文件直接加微信 Crazzy M 说明 上一节已经通过Matlab中基础的乘加运算进行了CNN网络的前向计算过程 该节利用Matlab将导出的CNN网络
  • Object365数据/论文说明

    总览 1 目标检测数据 365类 约600k训练图片 超过一千万的bboxes 迄今为止最大的目标检测数据集 全注释的 2 服务于更好的未来研究 局部敏感类型的任务 如目标检测 语义分割 3 在COCO测试下 Objects365上预训练的
  • IDEA插件系列(33):RestfulTool插件——Restful服务开发辅助工具集

    1 插件介绍 RestfulTool插件 一套 Restful 服务开发辅助工具集 提供了一个 Services tree 的显示窗口 双击 URL 直接跳转到对应的方法定义 一个简单的 http 请求工具 支持 Spring 体系 Spr
  • npm install安装依赖总结

    node下载地址 https nodejs org en download releases 可以看到node版本 npm版本 node module版本 1 npm的全局安装路径 查看默认值 npm get prefix 默认是C Use
  • 五、网络编程之网络 IO 模型的本质.md

    IO 网络模型的本质 前置概念 1 用户空间和内核空间 学习 Linux 或者 IO 网络模型时 经常可以看到两个词 User space 用户空间 和 Kernel space 内核空间 简单说 Kernel space 是 Linux
  • 实例创建流程_ABAQUS复合材料建模及基本分析流程

    案例1 创建开孔矩形复合材料常规壳层合板 层合板一端固定 另一端施加拉伸载荷 对模型进行分析 查看每层单方向的应力 对比云图和加载时的铺层额方向 理解铺层方向与lamina材料的概念 0 1建立几何模型 利用Abaqus中composite
  • javaSE基础 数据库操作3之数据库恢复

    java基础 数据库操作3之数据库恢复 流程 上一篇写了数据的备份 本篇将写数据库的恢复操作 思想 备份文件中写入的是将数据库表转换为sql后的语句 所以备份就只需将备份文件中的sql语句执行即可 数据库恢复 public static v
  • uni-app转小程序遇到的问题 (组件使用插槽的问题)(跨端兼容、条件编译)(小程序自定义胶囊按钮封装)(uni-app挂载原型链)

    1 uni app转小程序组件使用插槽的问题 uni app封装的组件使用问题 1 插槽样式 H5页面编译是有效果的 在小程序中编译的位置错误 它会跳出本来的插槽位置到最后 解决方法 使用父传子传递值 就可以继承组件的样式 封装的组件 使用
  • python使用from keras.utils import to_categorical出错

    python使用from keras utils import to categorical出错 我使用的python编辑环境Sublime Text keras的版本2 6 0 结果语句from keras utils import to
  • 【WiFi】国产WiFi芯片

    目录 1 概述 2 WiFi芯片的市场格局 3 中国的WiFi芯片公司 3 1 华为海思 3 2 乐鑫科技 3 3 博通集成 3 4 紫光展锐 3 5 康希通信 3 6 南方硅谷 4 国产WiFi芯片竞争格局 4 1 内卷WiFi 4 4
  • 芯片后端开发基础知识(二)

    目录 1 静态时序分析 Static Timing Analysis 2 波形的压摆 Slew 3 信号偏斜 Skew 4 时序路径 Clock Path 5 时序弧 Timing Arc 6 时钟域 Clock Domain 7 工作环境
  • 【IPC-UNIX网络编程】第4章管道和FIFO

    1 一个简单的客户 服务器例子 Client从标准输入 stdin 读进一个路径名 并把它写入IPC通道 Server从该IPC通道读出这个路径名 并尝试打开其文件 若server能打开该文件 它能读出其中的内容 并写入 不一定同一个 IP
  • 本科毕设——基于人脸识别的签到系统的研究

    本人普通四非本科 毕设选了这个比较大众且成熟的选题 四处借鉴后完成了论文 现在写写一些我完成毕设期间的历程 在完成论文开题报告后我开始寻求代码以期完成一个简易人脸识别签到系统的设计 开始我用了舍友选修课人工智能的大作业 他所采用的是传统的h
  • Adapter模式——设计模式学习笔记

    Adapter模式 一 意图 将一个类的接口转换成客户希望的另外一个接口 Adapter模式使得原本由于接口不兼容而不能在一起工作的那些类可以在一起工作 二 动机 为复用而设计的通用的类 总是存在一些特殊的情况 使其不能够使用或者完成相应的
  • pt工具常用命令

    pt工具介绍 Percona Toolkit简称pt工具 是Percona公司开发用于管理MySQL的工具 功能包括检查主从复制的数据一致性 检查重复索引 定位IO占用高的表文件 在线DDL等 DBA熟悉掌握后将极大提高工作效率 下载地址h
  • YOLO物体检测-系列教程2:YOLOV2整体解读

    YOLO 系列教程 总目录 YOLOV1整体解读 YOLOV2整体解读 YOLOV2提出论文 YOLO9000 Better Faster Stronger 1 YOLOV1 优点 快速 简单 问题1 每个Cell只预测一个类别 如果重叠无
  • 第二十七课、应用程序中的主窗口------------------狄泰软件学院

    一 主窗口的概念 1 应用程序中的主窗口 1 主窗口是与用户进行长时间交互的顶级窗口 2 程序的绝大多数功能直接由主窗口提供 3 主窗口通常是应用程序启动后显示的第一个窗口 4 整个程序由一个主窗口和多个对话框组成 2 Qt中的主窗口 1
  • leetcode排序算法总结—时间复杂度o(nlogn)-希尔/堆排/快排/归并小记

    排序算法总结 时间复杂度O nlogn 希尔 堆排序 快排 归并 希尔排序 有一段间隔的排序 可以逐个子表进行排序 然 例如王道 都给出便于计算机进行连续访问的程序算法 即依次按元素比较不同子表进行子表的调整 时间复杂度O n 1 3 最坏