DS:排序

DS排序--希尔排序 题目描述 给出一个数据序列,使用希尔排序算法进行降序排序。 间隔gap使用序列长度循环除2直到1 输入 第一行输入t,表示有t个测试示例 第二行输入n,表示第一个示例有n个数据(n>1) 第三行输入n个数据,都是正整数,数据之间用空格隔开 以此类推 输出 对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。 样例输入 2 6 111 22 6 444 333 ... 阅读详情

好吧,我现在没有网,我现在就只能做一下这些线下的工作

那我准备在下午完成排序算法和STL的整理

数据结构也基本上就只差排序和那个字符串的KMP算法了

1 排序算法

排序算法的稳定性:

如果元素中有两个元素k1, k2,排序之前k1排在k2前面,排序之后k1也是排在k2前面,则称排序是稳定的

内排序和外排序

内排序就是说排序过程中数据都在内存里,不用来回交换;外排序就是数据在内存一部分在外存一部分啦

性能评估

数据比较次数和数据移动次数

靠 我刚写了几行字就有网了,好吧,那也得等我写完这一篇吧

2 插入排序

2.1 直接插入排序

核心思想:插入第i个元素时,前面i - 1个元素都已经排好序了

```C++
void insert_sort(vector<int>& v)
{
    int n = v.size();
    for(int i = 1; i < n; i++)
    {
        for(int j = 0; j < i; j++)
        {
            if(v[i] < v[j])
            {
                int k = i;
                int tmp = v[i];
                while(k > j)
                {
                    v[k] = v[k - 1];
                    k--;
                }
                v[j] = tmp;
                break;
            }
        }
    }
}
```

时间复杂度O(n^2)

2.2 二分排序

在插入第i个元素时,前i - 1个元素都已经排好序, 利用折半查找的思路查找v[i]的插入位置

也就是将直接插入排序的查找比较过程变成了折半查找

```C++
void binary_insert_sort(vector<int>& v)
{
    int n = v.size();
    for(int i = 1; i < n; i++)
    {
        int left = 0;
        int right = i - 1;
        int mid = (left + right) / 2;
        int tmp = v[i];
        while(left <= right)
        {
            mid = (left + right) / 2;
            if(tmp < v[mid])
                right = mid - 1;
            else if(tmp > v[mid])
                left = mid + 1;
            else
            {
                left = mid + 1;
                break;
            }
        }
        for(int j = i - 1; j >= left; j--)
            v[j + 1] = v[j];
        v[left] = tmp; 
    }
}
```

折半插入排序也是稳定的

时间复杂度为O(n * logn)

2.3 希尔排序

核心思想:交换不相邻元素以对数组进行局部排序,再使用插入排序使局部有序的数组有序(gap = 1)

使用一个gap作为间隔,用插入排序是得每个间隔i, i + gap, i + 2 * gap有序

随着gap减少到1,就可以变成整个数组插入排序(但是很多已经局部有序)

为什么选择插入排序呢?因为基本上已经局部有序了,插入排序在最好情况下为O(n),且数量较少时较为有效

```C++
void shell_sort(vector<int>& v)
{
    int n = v.size();
    int gap = n - 1;
    do
    {
        gap = gap / 3 + 1;
        for(int i = gap; i < n; i++)
        {
            for(int j = i; j >= gap; j -= gap)
            {
                if(v[j] < v[j - gap])
                {
                    int tmp = v[j - gap];
                    v[j - gap] = v[j];
                    v[j] = tmp;
                }
            }
        }
    }while(gap > 1);
}
```

举个例子就理解了:
在这里插入图片描述

无法证明,但对任意数组表现也不错,小于O(n^2),不稳定排序

3 交换排序

3.1 冒泡排序

非常简单的一种时间复杂度为O(n^2)的排序算法

核心思想就是:第一层循环表示多少趟, 第二层循环表示从哪到哪两两交换,如果前面比后面大,就交换(也就是把大的换到后面)

```C++
void bubble_sort(vector<int>& a)
{
    int n = a.size();
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < n - 1 - i; j++)
        {
            if(a[j] > a[j + 1])
            {
                int tmp = a[j + 1];
                a[j + 1] = a[j];
                a[j] = tmp;
            }
        }
    }
}
```

也是稳定的

```C++
void bubble_sort(vector<int>& a)
{
    int n = a.size();
    for(int i = 0; i < n; i++)
    {
        int flag = false;
        for(int j = 0; j < n - 1 - i; j++)
        {
            if(a[j] > a[j + 1])
            {
                int tmp = a[j + 1];
                a[j + 1] = a[j];
                a[j] = tmp;
                flag = true;
            }
        }
        if(!flag)return;
    }
}
```

改进就是设置一个标志,如果这一遍冒泡没有交换任何元素,说明已经有序了,那就直接返回就好了

3.2 快速排序

典型的分治法, 选一个基准点(随便选), 通过移动使得基准点左边都是比他小的,右边都是比他大的,然后分别进入两边再排序.

对于移动元素, 快速排序是冒泡排序的改进, 不是通过不断比较交换的(相邻交换), 是直接将两个交换(跳跃交换), 但是我们又不需要把基准点赋值,最后赋值即可.

```C++
int partition(vector<int>& v, int low, int high)
{
    int key = v[low];//基准点选最左边
    while(low < high)
    {
        while(low < high && v[high] >= key) high--; //从右边开始, 右边大于key的就过掉
        if(v[high] < key)   //如果有小于key的就和左边未检查的部分交换,但是其实我们不需要真的把左边的赋值过来,后面会处理的
        {
            v[low] = v[high];
            low++;
        }
        while(low < high && v[low] <= key) low++;//同样,再过掉左边比key小的
        if(v[low] > key)//找到一个大的,就交换到右边未处理的那
        {
            v[high] = v[low];
            high--;
        }
    }
    v[low] = key;//结束的时候low==high,就是key应该在的位置
    return low;
}
//另一个更好理解的版本
int partition(vector<int>& v, int low, int high)
{
    int keypos = low;
    int key = v[low];
    for(int i = low + 1; i < high; i++)
    {
        if(v[i] < key)
        {
            keypos++;//keypos已左都是小于key的,如果小于key,我们就把v[i]放在keypos上,把原来那些大于未处理的交换到后面去
            if(keypos != i)
            {
                int tmp = v[i];
                v[i] = v[keypos];
                v[keypos] = tmp;
            }
        }
    } 
    v[low] = v[keypos];
    v[keypos] = key;
    return keypos;
}
void  quick_sort(vector<int>& v, int low, int high)
{
    if(low < high)
    {
        int k = partition(v, low, high);
        quick_sort(v, low, k - 1);
        quick_sort(v, k + 1, high);
    }
}
```

快速排序也是不稳定的, 时间复杂度为O(nlogn), 是性能最好的一种内排序方法

时间复杂度取决于递归树的高度,最好情况是完全二叉树,最坏情况是单链树

快速排序的运行时间取决于输入序列, 对n较大的平均情况下, 快速排序效果较好, 对于n较小的情况下, 快排效果比简单排序效果差

快速排序的改进

我们上面说到如果规模很小时,使用直接插入排序是一个很好的办法,所有我们可以设置在high - low < M时选择直接插入排序;或者说我们小于一定规模就返回,这样最终得到的是一个基本上已经排好序的数组,我们再最后调用一遍直接插入排序就好了

还有基准元素的选择也对快速排序有影响,我们最希望的是左右平分, 基准元素位于中间,因此我们可以随机选择基准元素.

4 选择排序

4.1 简单选择排序

核心思想:选出未排序中最小的不断放在未排序的后面

```C++
void select_sort(vector<int>& v)
{
    for(int i = 0; i < v.size() - 1; i++)
    {
        int pos = i;
        for(int j = i + 1; j < v.size(); j++)
        {
            if(v[j] < v[pos])
                pos = j;
        }
        int tmp = v[pos];
        v[pos] = v[i];
        v[i] = tmp;
    }
}
```

不稳定排序算法, 时间复杂度也是O(n^2)

4.2 堆排序

见堆

5 归并排序

归并排序和快速排序类似, 也是基于分治法的, 将序列分成两个长度相等的子序列,对子序列进行排序,然后再将其合并.

归并排序不依赖输入序列, 避免了快排的最坏情况

所以, 归并排序主要包括两步: 划分 合并(合并两个有序表)

```C++
void merge(vector<int>& v, vector<int>& s, int left, int mid, int right)
{
    for(int i = 0; i < v.size(); i++)
        s[i] = v[i];
    int p1 = left, p2 = mid + 1, p = left; 
    while(p1 <= mid && p2 <= right)
    {
        if(s[p1] < s[p2])
            v[p++] =s[p1++];
        else
            v[p++] = s[p2++];
    }
    while(p1 <= mid)
        v[p++] = s[p1++];
    while(p2 <= right)
        v[p++] = s[p2++];
}
void merge_sort(vector<int>& v, vector<int>& s, int left, int right)
{
    if(left >= right)   return;
    int mid = (left + right) / 2;
    merge_sort(v, s, left, mid);
    merge_sort(v, s, mid + 1, right);
    merge(v, s, left, mid, right);
}
```

归并排序是一种稳定排序方法, 时间复杂度为O(nlogn), 空间复杂度需要一个O(n)的辅助数组

6 总结

  • 简单排序方法主要包括直接插入排序、冒泡排序、选择排序, 他们适合数量较小的序列,时间复杂度是O(n^2), 空间复杂度忽略不计

直接插入排序最好情况下能够只比较n - 1次,不用移动

改进的冒泡排序最好情况下, 也只比较n - 1次即可

选择排序比较次数与初始序列无关,都需要比较n^2次, 但是元素移动与初始有关

  • 快速排序、归并排序、堆排序都是比较高效的排序方法, 时间复杂度都在O(nlogn)

快排就是与选择的基准元素有关,归并排序就与初始序列无关

  • 希尔排序介于简单排序和高效排序之间

  • 稳定的算法有:冒泡、直接插入、折半插入、归并

手把手教你设计T型和Π型衰减器:从理论计算到实际搭建(含误差分析) 本文详细介绍了T型和Π型衰减器的设计方法,从理论计算到实际搭建,包括电阻值推导、元件选择技巧及误差分析。通过实例演示如何设计50Ω系统中的10dB衰减器,并提供了高频应用和优化策略,帮助电子工程师掌握阻抗匹配与信号衰减的核心技术。 阅读详情

相关推荐

Globus数据下载全攻略:从零配置到批量下载大文件(附常见问题解决)

本文详细介绍了Globus数据下载的全流程,从零配置到批量下载大文件的实用技巧,包括环境准备、高级传输策略、性能优化及常见问题解决方案。Globus作为科研数据的高效传输工具,通过并行流传输和自动校验技术,显著提升大规模数据传输的效率和可靠性。

u9v0w的博客 663

【DS】排序

1、直接选择排序 按升序排序,假设下标为0的数为最大值(max=0),用指针j从下标为0处开始遍历,找到比array[max]的值大的时候,max就为较大数的下标值,并把这个值放在最后一个位置,共有几个数,按此规律循环几次,循环过程中,无序数组的范围是:[0,array.length-i],有序数组为[array.length-i,array.length],代码如下: ` for(int i=0...

CHAOQIWEN的博客 530

node-red 可视化探索

配置socket选择配置流程产生url。

weixin_44133581的博客 3413

DS_【选择排序】

Java 四大排序 二、选择排序 (1)简单选择排序 排序过程描述 1.拿到一个数 依次与之后的每一个数进行比较 将最小的放在 原来第一的位置 2.拿到第二个数 与之后的进行比较 最小的放在第二的位置 3.第三个数 以此类推 直到最后一个数 排序结束 算法过程描述 1.循环遍历数组i 2.内嵌遍历i之后的数组 3.i 与 j进行大小比较 小的放前 代码实现 public static void...

java_Maxhui 861

高通camera:PDAF的配置与测试

确认相关log日志都已经打开了之后,判断是在3A算法中没有应用到PDAF,可能是之前在调试AF效果的时候关闭了PDAF,打开效果文件对应的文件夹,在\kamorta_lce_S5K3P9\Scenario.Default\XML\STATS。在log中搜索af_pdaf_proc_pd_single,这个函数是pdaf算法中的,源码被封装了,这里看不到,因此只能通过log打印出来的参数来分析pd是否正确,主要参数有pd ,defocus,confidence。PDAF的配置与测试。

arvin_xiong的博客 2487

Gromacs空蛋白模拟实战:从PDB文件到动力学轨迹的完整流程解析

本文详细解析了使用Gromacs进行空蛋白分子动力学模拟的完整实战流程。从PDB文件处理、力场选择与拓扑构建,到模拟盒子创建、溶剂化与电荷中和,再到能量最小化、NVT/NPT平衡及最终的生产模拟与基础分析,提供了每一步的命令详解和关键注意事项,旨在帮助计算生物学研究者系统掌握这一核心研究工具。

weixin_28454475的博客 276

【DS】八大排序思路及其优化

【算法】本文讲到了十个排序:插入排序,希尔排序,选择排序,堆排序,冒泡排序,快速排序,归并排序,计数排序,基数排序,桶排序,基本实现了各个排序的优化及改进。

weixin_56952690的博客 596

YOLOv13添加轻量化的EMA模块Faster_EMA,轻量又涨点!map50提升4.56个点,召回率提升9.66!

本文介绍了YOLOv13模型的优化移植方法,通过添加Faster_EMA模块和超参数调整,使模型性能显著提升。主要修改包括:1) 创建新的模型配置文件yolov13-Faster_EMA.yaml;2) 在tasks.py中添加新模块;3) 修改__init__.py和block.py文件,新增Partial_conv3和DropPath类。优化后模型mAP50提升4.56%,召回率提升9.66%,验证了改进方案的有效性。代码实现了局部卷积和随机深度等先进技术,为YOLO系列模型性能优化提供了新思路。

FJN110的博客 2605

DS排序--简单选择排序

题目描述 给出一个数据序列,使用简单选择排序算法进行升序排序 输入 第一行输入t,表示有t个测试示例 第二行输入n,表示第一个示例有n个数据(n>1) 第三行输入n个数据,都是正整数,数据之间用空格隔开 以此类推 输出 对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。 样例输入 2 6 21 25 49 25 16 8 8 30 13 70 85 39 42 6 20 样例输出 8 25 49 25 16 21 8 16 49 25 25 21 8 16 21 25 25 49 8 1.

半濠春水的博客 2637

RT-DETR改进策略【卷积层】| CVPR-2020 Strip Pooling 空间池化模块 处理不规则形状的对象 含二次创新

一、本文介绍 本文记录的是利用Strip Pooling模块优化RT-DETR的目标检测网络模型。Strip Pooling结合了长而窄的卷积核形状在一个空间维度上的长程关系捕捉能力和在另一个空间维度上的局部细节捕捉能力,有效地处理复杂的场景信息。这一机制通过采用1×N1×N1×N或N×1N×1N×1的池化核形状来适应不同的图像特征,提高模型对目标形状和分布的适应性。在场景解析网络中,Strip Pooling可以被用于提升对具有长程带状结构或离散分布目标的解析能力,特别是在复杂场景或不同对象布局条件下效果

Limiiiing的博客 580

LoRa学习:LoRa通信调制解调的实现原理与性能

LoRa学习:LoRa调制解调原理与性能 1、LoRa调制解调器原理 LoRa调制解调器采用专利扩频调制和前向纠错技术。与传统的FSK、OOK调制技术相比,LoRa扩大了无线通讯链路的覆盖范围(实现了远距离无线传输),提高了链路的鲁棒性。。 开发人员可调整扩频因子和纠错率这两个参数,从而平衡通讯时的带宽占用、通信速率、空中包的存活时间、以及抗干扰性等。。 LoRa调制解调器...

HowieXue 薛永浩的博客 3万+

DS初阶:八大排序之堆排序、冒泡排序、快速排序

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法

weixin_51142926的博客 5777

游戏战斗系统架构设计的演绎之路——从一坨意大利面条到一座精密钟表

摘要:游戏战斗系统架构设计的演进之路 本文系统梳理了游戏战斗系统从早期街机到现代3A大作的架构发展历程。70-80年代的街机游戏采用基础碰撞盒判定(如《街头霸王》);90年代实现动画融合与状态机架构(《最终幻想》《拳皇》);2000年后MMO引入服务器验证与同步技术(《魔兽世界》);3D时代融合物理引擎与智能AI(《GTA5》《只狼》);移动端则发展出轻量化架构与云端判定(《王者荣耀》)。现代战斗系统已实现模块化、数据驱动和热更新,未来趋势是AI裁判与云战斗系统。这一演进过程展现了技术与创意的完美结合,数百

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 801

DS初阶:八大排序之直接插入排序、希尔排序和选择排序

所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起 来的操作。

weixin_51142926的博客 7057

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

DS初阶:八大排序之归并排序、计数排序

归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。

weixin_51142926的博客 5679

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

A : DS二叉排序树之查找

从第二行起,输出查找结果,如果查找成功输出查找次数,如果查找失败输出-1。第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开。第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到。从第五行起,输入m行,每行一个要查找的数据,都是自然数。给出一个数据序列,建立二叉排序树,并实现查找功能。对二叉排序树进行中序遍历,可以得到有序的数据序列。第二行输入n,表示首个序列包含n个数据。第一行输入t,表示有t个数据序列。第四行输入m,表示要查找m个数据。以此类推输出下一个示例的结果。

m0_74745356的博客 728

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

A : DS二叉排序树之删除

给出一个数据序列,建立二叉排序树,并实现删除功能对二叉排序树进行中序遍历,可以得到有序的数据序列Input第一行输入t,表示有t个数据序列第二行输入n,表示首个序列包含n个数据第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开第四行输入m,表示要删除m个数据从第五行起,输入m行,每行一个要删除的数据,都是自然数以此类推输入下一个示例。

m0_73593528的博客 280

Re:从零开始的DS学习 十大排序算法我都整理好了

本文详细介绍了冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序、外部排序的算法流程和源码。供读者理解与学习,适合点赞+收藏。有什么错误希望大家直接指出~

小明的Java问道之路 6604

生产环境部署Qwen3-4B-Instruct-2507:vLLM与SGLang性能对比及优化策略

如何在生产环境中高效部署Qwen3-4B-Instruct-2507模型?这是许多AI开发者和企业面临的关键挑战。作为一款优秀的指令调优大语言模型,Qwen3-4B-Instruct-2507在推理任务中表现出色,但要在生产环境中实现高性能、低延迟的部署,选择合适的推理框架至关重要。本文将深入对比vLLM与SGLang两大主流推理框架的性能表现,并提供实用的优化策略,帮助您做出最佳选择。 ##

gitblog_00260的博客 442

C : DS二叉排序树之删除

第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开。第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到。从第五行起,输入m行,每行一个要删除的数据,都是自然数。从第二行起,输出删除第m个数据后的有序序列,输出m行。给出一个数据序列,建立二叉排序树,并实现删除功能。对二叉排序树进行中序遍历,可以得到有序的数据序列。第二行输入n,表示首个序列包含n个数据。第一行输入t,表示有t个数据序列。第四行输入m,表示要删除m个数据。以此类推输出下一个示例的结果。以此类推输入下一个示例。

m0_74745356的博客 551

PTA:jmu-ds-拓扑排序

给定一个有向图,求其拓扑序列,若有环路,输出error!

ly1012_的博客 476

ds二叉排序树之创建和插入_图解:什么是二叉排序树?

点击关注上方“五分钟学算法”,设为“置顶或星标”,第一时间送达干货。转自景禹景禹的写作风格还是一如既往的细腻:),欢迎关注他。以下为原文。今天我们谈一谈 二叉排序树 ,一种你会爱上的数据结构,当然人有优缺,二叉排序是也是如此,我们一起开动脑筋征服她吧。二叉排序树二叉排序树(Binary Sort Tree)或者是一颗空树;或者是具有如下性质的二叉树:(1) 若它的左子树不空,则 左子树 ...

weixin_31650287的博客 1801

E : DS二叉排序树之删除

写这篇是因为在网上找不到很简洁的。第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开。第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到。从第五行起,输入m行,每行一个要删除的数据,都是自然数。从第二行起,输出删除第m个数据后的有序序列,输出m行。给出一个数据序列,建立二叉排序树,并实现删除功能。对二叉排序树进行中序遍历,可以得到有序的数据序列。第二行输入n,表示首个序列包含n个数据。第一行输入t,表示有t个数据序列。第四行输入m,表示要删除m个数据。以此类推输出下一个示例的结果。

weixin_72796823的博客 465

问题 E: DS二叉排序树之查找

题目描述 给出一个数据序列,建立二叉排序树,并实现查找功能 对二叉排序树进行中序遍历,可以得到有序的数据序列 输入 第一行输入t,表示有t个数据序列 第二行输入n,表示首个序列包含n个数据 第三行输入n个数据,都是自然数且互不相同,数据之间用空格隔开 第四行输入m,表示要查找m个数据 从第五行起,输入m行,每行一个要查找的数据,都是自然数 以此类推输入下一个示例 输出 第一行输出有序的数据序列,对二叉排序树进行中序遍历可以得到 从第二行起,输出查找结果,如果查找成功输出查找次数,如果

qq_50065237的博客 379

【id:315】【20分】B. DS内排—堆排序

【id:315】【20分】B. DS内排—堆排序

weixin_74385534的博客 1152

【id:163】【20分】B. DS排序--直接插入排序

对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。给出一个数据序列,使用直接插入排序算法进行升序排序。第三行输入n个数据,都是正整数,数据之间用空格隔开。第二行输入n,表示第一个示例有n个数据(n>1)第一行输入t,表示有t个测试示例。

mjp12345pp的博客 587
上一篇: C++ STL : vector
下一篇: DS:哈希表
fff_421
博客等级 码龄7年 3粉丝 69原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值