稳定排序nlogn之归并排序_一维,二维

稳定排序:排序时间稳定的排序

稳定排序包括:归并排序(nlogn),基数排序【设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)) 】,冒泡排序(n^2),插入排序(n^2),交换排序(n^2),计数排序【n为数字个数,k为数字范围,O(n+k)】等。

Problem:对n个数进行排序,n<=100000,1s以内

正常来说我们都用qsort(c),sort(c++),但快速排序平均时间复杂度为nlogn,最坏时间复杂度为n^2。虽然c,c++中的快速排序经过优化(如随机化等),但是最坏时间复杂度仍然接近n^2……

Solution:

用归并排序,时间复杂度稳定在O(nlogn)。

n=10000           nlogn=132877

n=100000         nlogn=1660964

n=1000000       nlogn=19931568

其中2^10=1024,2^20=1024*1024约为1000000

Code:

一维和二维的区别在于数据类型的不同和比较方式的不同

一维:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define maxn 100000
 4  
 5 struct node
 6 {
 7     long x,y;
 8 };
 9  
10 struct node a[maxn+1],b[maxn+1];
11  
12 void mergesort(long l,long r)
13 {
14     long mid;
15     mid=(l+r) >> 1;
16     if (l!=mid) mergesort(l,mid);
17     if (mid+1!=r) mergesort(mid+1,r);
18     long i,j,k;
19     for (i=l;i<=r;i++)
20         b[i]=a[i];
21     i=l;
22     j=mid+1;
23     k=l;
24     while (i<=mid && j<=r)
25     {
26         if (b[i].x<b[j].x || (b[i].x==b[j].x && b[i].y<b[j].y))
27         {
28             a[k]=b[i];
29             i++;
30             k++;
31         }
32         else
33         {
34             a[k]=b[j];
35             j++;
36             k++;
37         }
38     }
39     if (i<=mid)
40     {
41         while (i<=mid)
42         {
43             a[k]=b[i];
44             i++;
45             k++;
46         }
47     }
48     else
49     {
50         while (j<=r)
51         {
52             a[k]=b[j];
53             j++;
54             k++;
55         }
56     }
57 }
58  
59 int main()
60 {
61     long n,i;
62     scanf("%ld",&n);
63     for (i=1;i<=n;i++)
64         scanf("%ld%ld",&a[i].x,&a[i].y);
65     mergesort(1,n);
66     printf("\n");
67     for (i=1;i<=n;i++)
68         printf("%ld %ld\n",a[i].x,a[i].y);
69     printf("\n");
70     return 0;
71 }
72 /*
73 5
74 1 2
75 2 3
76 2 1
77 1 5
78 3 3
79 */

二维:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define maxn 100000
 4
 5 struct node
 6 {
 7     long x,y;
 8 };
 9
10 struct node a[maxn+1],b[maxn+1];
11
12 void mergesort(long l,long r)
13 {
14     long mid;
15     mid=(l+r) >> 1;
16     if (l!=mid) mergesort(l,mid);
17     if (mid+1!=r) mergesort(mid+1,r);
18     long i,j,k;
19     for (i=l;i<=r;i++)
20         b[i]=a[i];
21     i=l;
22     j=mid+1;
23     k=l;
24     while (i<=mid && j<=r)
25     {
26         if (b[i].x<b[j].x && (b[i].x==b[j].x && b[i].y<b[j].y))
27         {
28             a[k]=b[i];
29             i++;
30             k++;
31         }
32         else
33         {
34             a[k]=b[j];
35             j++;
36             k++;
37         }
38     }
39     if (i<=mid)
40     {
41         while (i<=mid)
42         {
43             a[k]=b[i];
44             i++;
45             k++;
46         }
47     }
48     else
49     {
50         while (j<=r)
51         {
52             a[k]=b[j];
53             j++;
54             k++;
55         }
56     }
57 }
58
59 int main()
60 {
61     long n,i;
62     scanf("%ld",&n);
63     for (i=1;i<=n;i++)
64         scanf("%ld%ld",&a[i].x,&a[i].y);
65     mergesort(1,n);
66     printf("\n");
67     for (i=1;i<=n;i++)
68         printf("%ld %ld\n",a[i].x,a[i].y);
69     printf("\n");
70     return 0;
71 }
72 /*
73 5
74 1 2
75 2 3
76 2 1
77 1 5
78 3 3
79 */
时间: 2024-10-11 21:00:11

稳定排序nlogn之归并排序_一维,二维的相关文章

c++ 依据输入动态声明数组(一维,二维)

较早的编译器是不同意这样做的,所以一些书籍比方以Tc解说的书本都说数组的下标不能是变量.在vc6.0下亦是如此. 只是在一些较新的编译器如dev c++已经支持了,例如以下代码不会报错 #include <stdio.h> #include <stdlib.h> int main() { int a; int i; scanf("%d",&a); int c[a]; for( i =0 ;i<a;i++) scanf("%d",

[blog 机器视觉]一维二维码的提取、识别和产生

一维二维码的提取.识别和产生 零.相关说明: 在"jsxyhelu.cnblogs.com/机器视觉"栏目主要介绍和图像处理和机器视觉相关的的成套的解决方案.思路和软件集.希望能够为大家在实际工作中解决具体问题提供一些帮助. 一.背景资料: 现在一维码.二维码广泛使用于工业各方面.很多和图像处理相关的需求也有所涉及.这里也看过一些论文,里面有一些方法还是art-of-air的,也有一些具备一定参考价值.这里只是谈一谈一般情况下的提取和识别.对于特殊情况,肯定要特殊对待,其实本身是一个增

最大值子区间和的一维二维问题

一维问题:nyoj 44 子串和 链接:click here 题目大意:给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n. 思路:m是元素总个数,sum是第一个元素,将当前的第一个元素作为最大值max,之后依次输入,检查sum<0?是的话更新sum为当前输入值:否则累加,最后比较这样每次步骤的最大值. 代码: #include <stdio.h> #include <mat

【树状数组】树状数组一维二维模板

以下模板都是点更新,区间查询,如果是区间更新点查询,只需将利用lowbit的循环方向倒过来 一维: inline int lowbit(int x) { return x & -x; } void add(int x, int val) { for(int i = x; i <= n; i += lowbit(i)) C[i] += val; } int sum(int x) { int ret = 0; for(int i = x; i > 0; i -= lowbit(i)) re

一维 + 二维树状数组 + 单点更新 + 区间更新 详解

树状数组详解: 假设一维数组为A[i](i=1,2,...n),则与它对应的树状数组C[i](i=1,2,...n)是这样定义的: C1 = A1 C2 = A1 + A2 C3 = A3 C4 = A1 + A2 + A3 + A4 C5 = A5 C6 = A5 + A6 ................. C8 = A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 ................ 如图可知: 为奇数的时候他是代表他本身,而为偶数的时候则是代表着自

C# 链表去重 List 一维 二维 分别使用 Distinct() GroupBy() 方法

分别使用过List中Distinct(),GroupBy()实现链表的去重. 1.先上效果: 一维链表中分别有元素"aa","bb",'aa','aa',"cc",使用Distinct()方法后输出 aa,bb,cc 二维链表中类型为ClassA类型,其中对象的属性A分别为1,1,2,3,1,使用GroupBy()方法实则是分类,输出Key值分别为1,2,3. 2.上代码,类ClassA 1 class ClassA 2 { 3 private

资瓷区间修改+区间求和的树状数组(一维/二维)

一维:令 \(v_i\) 为差分数组,那么 \([0, k]\) 的前缀和就是 \(\sum{v_i(k+1-i)} = (k+1) \cdot \sum{v_i} + \sum{v_i \cdot (-i)}\),树状数组维护一下 \(v_i\) 和 \(v_i \cdot i\) 即可. template <typename I> struct Fenwick { struct Node { I v0, v1; void add(I d0, I d1) { v0 += d0; v1 +=

好多粉微信复制统计加粉系统_更新二维码长按识别统计等

很多客户开通了腾讯广点通等广告推广,有的广告是投放在微信或者qq客户端里面.那么推广页面就可以直接加入微信二维码,让用户直接长按识别,然后添加好友等操作.这样的好处不言而喻,省去了访客复制添加等多步操作,避免访客复制错误或者记忆错误的麻烦,也就减少了流失率,提高了添加好友的成功率. 好多粉为满足广大用户对推广的精细化统计数据的要求,在统计点击行为的前提下,率先新增支持长按识别等行为. 操作很简单,步骤如下: 使用所有功能前,请添加基础统计代码! 基础统计代码安装教程: 1.落地页管理中开启行为转

python 按二维数组的某行或列排序 (numpy lexsort)

lexsort支持对数组按指定行或列的顺序排序:是间接排序,lexsort不修改原数组,返回索引. 默认按最后一行元素有小到大排序, 返回最后一行元素排序后索引所在位置. 设数组a, 返回的索引ind, a可以是1维或2维数组,ind返回的是一维数组 对于一维数组, a[ind]就是排序后的数组. 对于二维数组下面会详细举例. import numpy as np >>> a array([[ 2,  7,  4,  2], [35,  9,  1,  5], [22, 12,  3,