《数据结构》专题14--排序

A - 数据结构实验之排序一:一趟快排

Description

给定N个长整型范围内的整数,要求输出以给定数据中第一个数为枢轴进行一趟快速排序之后的结果。

 

Input

连续输入多组数据,每组输入数据第一行给出正整数N(N < = 10^5),随后给出N个长整型范围内的整数,数字间以空格分隔。

Output

输出一趟快速排序后的结果,数字间以一个空格间隔,行末不得有多余空格。

Sample

Input 

8
49 38 65 97 76 13 27 49

Output 

27 38 13 49 76 97 65 49

Hint

 
// 一种快排模板 必须会自己写!!
// 建议模拟一遍,便于理解,光看代码难以真正明白
#include<bits/stdc++.h>
using namespace std;

void Quicksort(int a[], int s, int e) {// s 代表排序开始位置;e 代表排序终止位置。
    if(s>=e) return;// 保证开始位置在终止位置之前。
    int i = s, j = e;// 利用始末位置而不改变原值:所以增加两个新变量。
    int key = a[s];// key类似指针,开始时指向初始位置,即假设第一个数是有序的。
    while(j > i) {
        while(j > i && a[j] >= key)
            j--;// 必须从右边的在前面
        a[i] = a[j];
        while(j > i && a[i] <= key)
            i++;// 从前面得知,key == i,如果这两行在前面,那一定会先执行这个操作,这样不行
        a[j] = a[i];
    }// i == j 时跳出while循环
    // 如果不能理解建议在自己手画模拟一遍
    a[i] = key;// 以此时的a[i] 为分界线,前面的数一定比a[i]小,后面的一定比a[i]大
    // 再运用递归将a[i]前面的和后面的分别排好序
    // Quicksort(a, s , i-1);
    // Quicksort(a, i+1 ,e );
}
int a[500];
int main()
{
    int n;
    while(cin >> n){
        for(int i = 0; i < n; i++)
            cin >> a[i];
        Quicksort(a, 0, n - 1);
        for(int i = 0; i < n; i++)
            cout << a[i] << " ";
        cout << endl;
    }
    return 0;
}

**这个注释不太对mark一下

B - 数据结构实验之排序八:快速排序

Description

给定N(N≤10^5)个整数,要求用快速排序对数据进行升序排列,注意不得使用STL。

Input

输入数据第一行给出正整数N(≤10^5),随后给出N个整数,数字间以空格分隔。

Output

 输出排序后的结果,数字间以一个空格间隔,行末不得有多余空格。

Sample

Input 

8
49 38 65 97 76 13 27 49

Output 

13 27 38 49 49 65 76 97
#include<bits/stdc++.h>
using namespace std;

#define PI 3.14159265358979323846
const int N = 1e5 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
const ll LMANX = 0x3f3f3f3f3f3f3f3f;
int a[N];
void Quick_sort(int a[], int l, int r){
    if(l >= r) return;
    int i = l, j = r;
    int t = l;
    while(i < j){
        while(i < j && a[j] >= a[t]) j--;
        while(i < j && a[i] <= a[t]) i++;
        swap(a[i], a[j]);
    }
    swap(a[t], a[i]);
    Quick_sort(a, l, i-1);
    Quick_sort(a, i+1, r);
}
int main()
{
    int n;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &a[i]);
    }
    Quick_sort(a, 0, n-1);
    for(int i = 0; i < n; i++){
        if(i == n-1) printf("%d", a[i]);
        else printf("%d ", a[i]);
    }
    return 0;
}

C - 数据结构实验之排序六:希尔排序

Description

我们已经学习了各种排序方法,知道在不同的情况下要选择不同的排序算法,以期达到最好的排序效率;对于待排序数据来说,若数据基本有序且记录较少时, 直接插入排序的效率是非常好的,希尔排序就是针对一组基本有序的少量数据记录进行排序的高效算法。你的任务是对于给定的数据进行希尔排序,其中增量dk=n/(2^k)(k=1,2,3……)

Input

连续输入多组数据,每组输入数据的第一行给出一个正整数N(N <= 10000),随后连续给出N个整数表示待排序关键字,数字间以空格分隔。

Output

输出dk=n/2和dk=1时的结果。

Sample

Input 

10
10 9 8 7 6 5 4 3 2 1
10
-5 9 7 -11 37 -22 99 288 33 66

Output 

5 4 3 2 1 10 9 8 7 6
1 2 3 4 5 6 7 8 9 10
-22 9 7 -11 37 -5 99 288 33 66
-22 -11 -5 7 9 33 37 66 99 288

Hint

#include<bits/stdc++.h>
using namespace std;

#define PI 3.14159265358979323846
const int N = 1e4 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
const ll LMANX = 0x3f3f3f3f3f3f3f3f;
int n, gap;
int a[N];
void Shell_Sort(int a[]){
    for(int i = gap; i < n; i++){
        int j = i;
        while(j - gap >= 0 && a[j] < a[j-gap]){
            swap(a[j], a[j-gap]);
            j -= gap;
        }
    }
}
int main()
{
    while(~scanf("%d", &n)){
        for(int i = 0; i < n; i++){
            scanf("%d", &a[i]);
        }
        gap = n / 2;
        Shell_Sort(a);
        for(int i = 0; i < n; i++){
            if(i == n - 1) printf("%d\n", a[i]);
            else printf("%d ", a[i]);
        }
        gap = 1;
        Shell_Sort(a);
        for(int i = 0; i < n; i++){
            if(i == n - 1) printf("%d\n", a[i]);
            else printf("%d ", a[i]);
        }
    }
    return 0;
}

D - 数据结构实验之排序三:bucket sort

Description

根据人口普查结果,知道目前淄博市大约500万人口,你的任务是帮助人口普查办公室按年龄递增的顺序输出每个年龄有多少人,其中不满1周岁的按0岁计算,1到2周岁的按1岁计算,依次类推,大于等于100岁的老人全部按100岁计算。

Input

 输入第一行给出一个正整数N(<=5000000),随后连续给出N个整数表示每个人的年龄,数字间以空格分隔。

Output

 按年龄递增的顺序输出每个年龄的人口数,人口数为0的不输出,每个年龄占一行,数字间以一个空格分隔,行末不得有多余空格或空行。

Sample

Input 

10
16 71 17 16 18 18 19 18 19 20

Output 

16 2
17 1
18 3
19 2
20 1
71 1
#include<bits/stdc++.h>
using namespace std;

#define PI 3.14159265358979323846
const int N = 5e6 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
const ll LMANX = 0x3f3f3f3f3f3f3f3f;
int a[N];
int b[N];
int main()
{
    int n, m;
    scanf("%d", &n);
    for(int i = 0; i < n; i++){
        scanf("%d", &m);
        if(m >= 100) a[100]++;
        else a[m]++;
    }
    for(int i = 0; i <= 100; i++){
        if(a[i] != 0) printf("%d %d\n", i, a[i]);
    }
    return 0;
}

E - 超排序

Description

bLue 在跨年之际获得了一份小礼物,里面装了一串只包含大写字母和小写字母的字符串,如果你能帮 bLue 把这个字符串按照字典序排序(按 ASCII 码从小到大排序。大写字母的 ASCII 码小于小写字母的 ASCII 码),他会奖励你一个 Accepted。

Input

输入数据有多组(数据组数不超过 50),到 EOF 结束。

对于每组数据,输入一行只包含大写字母和小写字母的字符串,且长度不超过 1000000。

Output

对于每组数据,输出一行排序后的字符串。

Sample

Input 

HappyNewYear
aaabAAbbBcdAB

Output 

HNYaaeepprwy
AAABBaaabbbcd

Hint

由于数据量较大,不推荐直接使用 cin, cout 输入输出。

另外,请确保最终结果是直接输出整个字符串,而非使用 printf("%c") 或 putchar() 等函数一个一个地输出字符,否则可能导致超时。

#include<bits/stdc++.h>
using namespace std;
// 另类桶排序
#define PI 3.14159265358979323846
const int N = 1e6 + 100;
const int M = 2e2 + 100;
const int MAXN = 0x3f3f3f3f;
typedef long long ll;
const ll LMANX = 0x3f3f3f3f3f3f3f3f;
char s[N];
int b[207];
int main()
{
    while(~scanf("%s", s)){
        memset(b, 0, sizeof(b));// 先清空每组测试的b[]
        int n = strlen(s);
        int t = 0;
        for(int i = 0; i < n; i++){
            b[s[i]]++;
        }
        for(int i = 'A'; i <= 'Z'; i++){
            for(int j = 1; j <= b[i]; j++){
                s[t++] = i;
            }
        }// 大写字母的ASCII码小,在前面
        for(int i = 'a'; i <= 'z'; i++){
            for(int j = 1; j <= b[i]; j++){
                s[t++] = i;
            }
        }// 小写字母在后面
        puts(s);
    }
    return 0;
}

F - 数据结构实验之排序四:寻找大富翁

Description

2015胡润全球财富榜调查显示,个人资产在1000万以上的高净值人群达到200万人,假设给出N个人的个人资产值,请你快速找出排前M位的大富翁。

Input

首先输入两个正整数N( N ≤ 10^6)和M(M ≤ 10),其中N为总人数,M为需要找出的大富翁数目,接下来给出N个人的个人资产,以万元为单位,个人资产数字为正整数,数字间以空格分隔。

保证所有的数据大小均在int范围内。

Output

一行数据,按降序输出资产排前M位的大富翁的个人资产值,数字间以空格分隔,行末不得有多余空格。

Sample

Input 

6 3
12 6 56 23 188 60

Output 

188 60 56

Hint

请用堆排序完成。

// 堆排序
#include<bits/stdc++.h>
using namespace std;

int heap[20], sz;
int res[20], cnt;
// 堆的两个操作:上升、下降
// 
void up(int u){
    while(u / 2 && heap[u/2] > heap[u]){
        swap(heap[u/2], heap[u]);
        u /= 2;
    }
}
void down(int u){
    int t = u;
    if(u*2 <= sz && heap[u*2] < heap[t]) 
        t = u * 2;
    if(u*2+1 <= sz && heap[u*2+1] < heap[t])
        t = u * 2 + 1;
    if(t != u){
        swap(heap[t], heap[u]);
        down(t);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    // 上面三行是为了提高c++代码运行效率
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        int num;
        cin >> num;
        if(sz < m){
            heap[sz] = m;
            sz++;
            up(sz);
        }
        else{
            if(heap[1] < num){
                heap[1] = num;
                down(1);
            }
        }
    }// 本题只要排好前m个就行
    while(m--){
        res[++cnt] = heap[1];
        heap[1] = heap[sz];
        sz--;
        down(1);
    }
    for(int i = cnt; i >= 1; i--)
        cout << res[i] << " ";
    return 0;
}

G - 数据结构实验之排序五:归并求逆序数

Description

对于数列a1,a2,a3…中的任意两个数ai,aj (i < j),如果ai > aj,那么我们就说这两个数构成了一个逆序对;在一个数列中逆序对的总数称之为逆序数,如数列 1 6 3 7 2 4 9中,(6,4)是一个逆序对,同样还有(3,2),(7,4),(6,2),(6,3)等等,你的任务是对给定的数列求出数列的逆序数。

Input

输入数据N(N <= 100000)表示数列中元素的个数,随后输入N个正整数,数字间以空格间隔。

Output

输出逆序数。

Sample

Input 

10
10 9 8 7 6 5 4 3 2 1

Output 

45
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值