首页 > 其他分享 >排序

排序

时间:2023-07-05 11:25:15浏览次数:30  
标签:sort const int MAXN 排序 cmp

排序的一些性质

通过比较操作来给同类元素排序。

可排序性

要求比较规满足可排序性:

任意两个待排序的元素都可以进行比较

比较规则满足传递性

例如,石头剪刀布不满足可排序性。这谁都知道

稳定性

排序后相等元素的位置是否发生变化

如果一定不发生变化,那么我们称它为稳定的排序

如果可能发生变化,那我们称它为不稳定的排序

逆序对

处于逆序关系的一对元素:存在下标\(i,j,(i < j)\),满足\(a_{i} > a_{j}\),称\((i,j)\)为一对逆序对

例题:逆序对统计

题目让我们求出\(n\)个不重复的数中有多少个逆序对

既然这题数据够小,那我们就可以……手打暴力(我为什么想到了柠季手打柠檬茶!)

示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e3 + 10;

int n,ret,a[MAXN];

int main(){

  cin >>n;

  for (int i = 1; i <= n; i++){

    cin >> a[i];
  }

  for (int i = 1; i <= n; i++){

    for (int j = i + 1; j <= n; j++){

      ret += a[i] > a[j] ? 1 : 0;
    }
  }

  cout << ret;

  return 0;
}

排序函数

C++ STL(Standard Library,标准库)中通过<algorithm>头文件中的函数sort()stable_sort()预先实现了一些排序算法,只不过,sort()不稳定,而stable_sort()是稳定的。

用法:函数名(起始地址,结束地址,比较器);,表示按比较器函数实现的排序规则对(起始地址,结束地址)做排序,其中比较器是可选参数

sort()stable_sort()都是基于比较的排序,平均需要\(n \cdot \log(n)\)次的元素比较和移动,其中\(n\)表示待排序元素的数量。基于比较的排序时间复杂度至少为\(O(n \cdot \log(n))\)。

例题:数字排序1

题目让我们从小到大排序,我们就可以用sort函数啦~

示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;

int n,a[MAXN];

int main(){

  cin >> n;

  for (int i = 1; i <= n; i++){

    cin >> a[i];
  }

  stable_sort(a + 1,a + n + 1);

  for (int i = 1; i <= n; i++){

    cout << a[i] <<' ';
  }

  return 0;
}

比较器

用函数实现的自定义比较规则。

在\(C++\)中,比较器接受两个同类型参数,第一个参数靠前时返回\(true\),否则返回\(false\)(包括相等的情况)

例如:大数靠前的比较器:

bool cmp(int i,int j){

    return i > j;
}

例题:数字排序2

题目让我们从小到大排序,我们又可以用sort函数啦~(

当然我们需要一个cmp函数

示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;

int n,a[MAXN];

bool cmp(int x,int y){

  return x > y;
}

int main(){

  cin >> n;

  for (int i = 1; i <= n; i++){

    cin >> a[i];
  }

  stable_sort(a + 1,a + n + 1,cmp);

  for (int i = 1; i <= n; i++){

    cout << a[i] << ' ';
  }

  return 0;
}

结构体排序!

重点终于来了(

结构体排序是指开一个结构体,这知道吧,在写一个cmp函数,这也知道吧,然后修改一下cmp,把里面的return语句改一下,假设是这样的:

const int MAXN = 1e5 + 10;

struct Student{
    
    int c,id;
}a[MAXN];

可见这是一个结构体,确切地说,是一个用来存储学生的某某某东西的结构体,然后我们要对它进行排序,怎么排呢?如果你要排的是\(c\)(默认小数靠前),那么cmp就这么写:

bool cmp(const Student &a, const Student &b){

    return a.c < b.c;
}

然后如果你要排的是\(id\)(还是小数靠前),就这么写:

bool cmp(const Student &a, const Student &b){

    return a.id < b.id;
}

例题1:排序与编号

题目让我们给长度为\(n\)的数组排序,然后输出排序后的编号,那么我们可以这样,先写一个结构体,里面有\(c,id\)两个值,还有一个用来存储数据的\(Node\)类型的\(a\)数组:

const int MAXN - 1e5 + 10;

struct Node{

    int c,id;
}a[MAXN];

然后,就是刚刚讲的结构体排序,因为题目给的是让我们从小到大排序

bool cmp(const Node a, const Node b){

    return a.c < b.c;
}

注意:这里要写的是\(a.c\),而不是\(a.id\),因为不是给\(id\)排序。

完整示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;

int n;

struct node{

  int id,c;
}a[MAXN];

bool cmp(node x,node &y){

  return x.c < y.c;
}

int main(){

  cin >> n;

  for (int i = 1; i <= n; i++){

    cin >> a[i].c;

    a[i].id = i;
  }

  sort(a + 1, a + n + 1,cmp);

  for (int i = 1; i <= n; i++){

    cout << a[i].id << ' ';
  }

  return 0;
}

例题2:多关键字排序

题目让我们给同学们的\(m\)课成绩排序,并按顺序输出排序后的学号,我们还是写结构体排序,注意是有\(m\)科,所以结构体里面还需要一个数组。

示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e4 + 10,maxn = 1e1 + 10;

int n,m;

struct Student{

    int km[maxn];
}stu[MAXN];

bool cmp(Student &a,Student &b){

    for (int i = 1; i <= m; i++){

        if (a.km[i] != b.km[i]){

            return a.km[i] > b.km[i];
        }
    }

    return false;
}

int main(){

    cin >> n >> m;

    for (int i = 1; i <= n; i++){

        for (int j = 1; j <= m; j++){

            cin >> stu[i].km[j];
        }
    }

    sort(stu + 1,stu + n + 1,cmp);

    for (int i = 1; i <= n; i++){

        for (int j = 1; j <= m; j++){

            cout << stu[i].km[j] << ' ';
        }

        cout << '\n';
    }

    return 0;
}

重载<运算符

排序函数使用<符号来比较。通过在结构体内重载<运算符,可以让排序函数支持结构体排序的比较规则,类似于比较器。

格式:

bool operator < (const Node & i) const{
    //...
}
//Node为结构体类型名称,i为对象名
//在大括号中实现比较规则,const表示该运算符不能对成员进行修改操作

例题:区间排序

题目让我们按照左边界和右边界排序,这里分为两种情况:

1,左边界不同

2,左边界相同

这两个东西要写一个||符号,左边界相同和另一个条件(右边界不同)要写&&

示例Code:

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e5 + 10;

int n;

struct node{

    int l,r;

    bool operator < (const node &k) const {

        return l < k.l ||l == k.l && r < k.r;
    }
}a[MAXN];

int main(){

    cin >> n;

    for (int i = 1; i <= n; i++){

        cin >> a[i].l >> a[i].r;
    }

    sort(a + 1, a + n + 1);

    for (int i = 1; i <= n; i++){

        cout << a[i].l << ' ' << a[i].r << '\n';
    }

    return 0;
}

完结撒花!

这么长的东西,我可写了好久

标签:sort,const,int,MAXN,排序,cmp
From: https://www.cnblogs.com/codehyx-blog/p/17528023.html

相关文章

  • linux 中ls命令实现对文件的排序
     001、ls默认是按照文件名称顺序列出的[root@PC1test02]#ls##测试文件a.txtb.txtc.txt[root@PC1test02]#ls-l##默认按照文件名称顺序total125000-rw-r--r--.1rootroot15360000Jul419:45a.txt-rw-r--r--.1......
  • 简单选择排序
    简单选择排序是一种基本的排序算法,它的思想是每次从待排序的序列中选择一个最小(或最大)的元素,放到已排序的序列末尾,直到所有元素都排好序。它的时间复杂度是O(n^2),空间复杂度是O(1)。下面是简单选择排序的JAVA实现:publicclassSelectionSort{publicstaticvoidsort(int......
  • 简单插入排序
    简单插入排序是一种基本的排序算法,它的思想是将待排序的元素逐个插入到已经有序的数组中,从而得到一个新的有序数组。它的时间复杂度是O(n^2),空间复杂度是O(1),是一种稳定的排序算法。简单插入排序的过程如下:从第二个元素开始,依次取出每个元素,与前面已经有序的元素进行比较。如......
  • 计数排序
    计数排序是一种非比较的排序算法,它的时间复杂度是O(n+k),其中n是待排序数组的长度,k是数组中的最大值。计数排序的基本思想是,对于每个输入元素x,确定小于等于x的元素个数,然后把x放在输出数组中对应的位置上。为了实现这个过程,需要一个额外的数组C,用来存储每个元素出现的次数,以及一个......
  • 桶排序算法及其Java实现
    桶排序是一种排序算法,它的原理是将数组分到有限数量的桶里,每个桶再个别排序,最后依次把各个桶中的记录列出来。桶排序的效率取决于映射函数的选择和桶的数量。桶排序适用于数据分布比较均匀,或者比较侧重于区间数量的情况。下面是我为你写的博客正文,希望对你有帮助:桶排序算法及其J......
  • 记录一下Oracle排序 将空值排在最后面
    select*fromtableorderbyxxx(字段)desc 今天在写Oracle排序的时候突然发现,Oracle默认将null值放最上面使用nullsfirst或者nullslast语法Nullsfirst和nullslast是OracleOrderby支持的语法如果Orderby中指定了表达式Nullsfirst则表示null值的记录将排在最前( ......
  • 【numpy基础】--数组排序
    numpy数组通常是用于数值计算的多维数组,而排序功能可以快速、准确地对数据进行排序,从而得到更加清晰、易于分析的结果。在数据分析和处理过程中,常常需要对数据进行排序,以便更好地理解和发现其中的规律和趋势。排序会应用在很多场景中,比如:数据分类:将数据按照一定的特征进行分......
  • C++面试八股文:std::array如何实现编译器排序?
    C++面试八股文:std::array如何实现编译器排序?某日二师兄参加XXX科技公司的C++工程师开发岗位第25面:面试官:array熟悉吗?二师兄:你说的是原生数组还是std::array?面试官:你觉得两者有什么区别?二师兄:区别不是很大,原生数组(非动态数组)和std::array都在栈上开辟空间,初始化的时候......
  • 堆排序
    求最小的K个数 publicint[]getLeastNumbers(int[]arr,intk){if(arr.length==0||k==0){returnnewint[0];}//构建小顶堆buildHeap(arr);//弹出堆顶重排序int[]rsp=newint[k];f......
  • 选读SQL经典实例笔记01_检索和排序
    1. 在WHERE子句中引用别名列1.1. 当表里的某些列没有被恰当命名的时候,这个技巧尤其有用1.2. sqlselectsalassalary,commascommissionfromempwheresalary<50001.3. 内嵌视图1.3.1.  sqlselect*from(selectsalassalary,commascommission......