排序专题整理

A. DS排序–希尔排序

题目描述
给出一个数据序列,使用希尔排序算法进行降序排序。

间隔gap使用序列长度循环除2直到1

输入
第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据(n>1)
第三行输入n个数据,都是正整数,数据之间用空格隔开
以此类推

输出
对每组测试数据,输出每趟排序结果。不同组测试数据间用空行分隔。

输入样例

2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222

输出样例

444 333 55 111 22 6
444 333 111 55 22 6

444 555 666 2222 77 77 33 1
666 2222 444 555 77 77 33 1
2222 666 555 444 77 77 33 1

C++ 代码

#include <iostream>
using namespace std;
int n;
int nums[1000];

int main(){
    int t;
    cin >> t;

    while (t--){
      cin >> n;

      for (int i = 0; i < n; ++i) cin >> nums[i];

      for (int gap = n/2; gap > 0; gap /= 2){
          for (int i = gap; i < n; ++i){
              int j = i;

              while (j- gap >= 0 && nums[j] > nums[j-gap]){
                  swap(nums[j], nums[j-gap]);
                  j -= gap;
              }
          }
          for (int k = 0; k < n; ++k){
              if (k < n-1) cout << nums[k] << " ";
              else cout << nums[k] << endl;
          }
      }
      cout << endl;
    }

    return 0;
}

B. DS排序–快速排序

题目描述
给出一个数据序列,使用快速排序算法进行从小到大的排序

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入
第一行输入t,表示有t个测试示例
第二行输入n,表示第一个示例有n个数据
第三行输入n个数据,都是正整数,数据之间用空格隔开
以此类推

输出
每组测试数据,输出每趟快排的结果,即每次排好一个数字结果(长度为1的子序列,不用排,不用输出)。不同测试数据间用空行分隔。

输入样例

2
6
111 22 6 444 333 55
8
77 555 33 1 444 77 666 2222

输出样例

55 22 6 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444
6 22 55 111 333 444

1 33 77 555 444 77 666 2222
1 33 77 555 444 77 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222
1 33 77 77 444 555 666 2222


C++ 代码

#include <iostream>
using namespace std;
int n;
int nums[100];

void quick_sort(int low, int high){
    int l = low, r = high;
    if (l >= r) return ;
    nums[0] = nums[low];
    int piv = nums[low];

    while (low < high){
        while (low < high && nums[high] >= nums[0]) --high;
        nums[low] = nums[high];
        while (low < high && nums[low] <= nums[0]) ++low;
        nums[high] = nums[low];
    }
    nums[low] = nums[0];
    for (int k = 1; k <= n; ++k){
        if (k < n) cout << nums[k] << " ";
        else cout << nums[k] << endl;
    }
    quick_sort(l, low-1);
    quick_sort(low+1, r);
}



int main(){
    int t;
    cin >> t;

    while (t--){
      cin >> n;

      for (int i = 1; i <= n; ++i) cin >> nums[i];

      quick_sort(1, n);
      cout << endl;
    }

    return 0;
}

C. DS内排—直插排序

题目描述
给定一组数据,使用直插排序完成数据的升序排序。

–程序要求–
若使用C++只能include一个头文件iostream;若使用C语言只能include一个头文件stdio
程序中若include多过一个头文件,不看代码,作0分处理
不允许使用第三方对象或函数实现本题的要求

输入
数据个数n,n个数据

输出
直插排序的每一趟排序结果

输入样例

7 34 23 677 2 1 453 3

输出样例

23 34 677 2 1 453 3
23 34 677 2 1 453 3
2 23 34 677 1 453 3
1 2 23 34 677 453 3
1 2 23 34 453 677 3
1 2 3 23 34 453 677


C++ 代码

#include <iostream>
using namespace std;
int n;
int nums[1000];

int main(){
    cin >> n;
    for (int i = 0; i < n; ++i) cin >> nums[i];

    for (int i = 1; i < n; ++i){
        int temp = nums[i];
        int j;
        for (j = i; j > 0; --j){
            if (temp <  nums[j-1]) nums[j] = nums[j-1];
            else break;
        }
        nums[j] = temp;
        for (int k = 0; k < n; ++k){
            if (k < n-1) cout << nums[k] << " ";
            else cout << nums[k] << endl;
        }
    }

    return 0;
}

D. 冒泡排序

题目描述
给定一个包含从0到n-1各一次的数组,若使用冒泡排序将其排为升序,问其中需要进行多少次交换

输入
测试数据有多组,

每组由两行组成:第一行包含正整数n(n <= 5000); 下一行包含从0到n-1的n个整数的序列。

输出
对于每组测试数据,

输出交换次数

输入样例

10
1 3 6 9 0 8 5 7 4 2

输出样例

22

C++ 代码

#include <iostream>
using namespace std;
int n;
int nums[5005];

int main(){
    while (cin >> n){
        for (int i = 0; i < n; ++i) cin >> nums[i];
        int cnt = 0;
        for (int i = 0; i < n-1; ++i){
            bool flag = false;
            for (int j = 0; j < n-1-i; ++j){
                if (nums[j] > nums[j+1]){
                    swap(nums[j], nums[j+1]);
                    flag = true;
                    cnt++;
                }
            }

            if (!flag) break;
        }
        cout << cnt << endl;
    }



    return 0;
}

E. DS内排—2-路归并排序

题目描述
输入一组字符串,用2-路归并排序按字典顺序进行降序排序。

输入
测试次数t

每组测试数据:数据个数n,后跟n个字符串,字符串不含空格。

输出
对每组测试数据,输出2-路归并排序的每一趟排序结果。每组测试数据的输出之间有1空行。

输入样例

2
6 shenzhen beijing guangzhou futian nanshan baoan
10 apple pear peach grape cherry dew fig haw lemon marc



输出样例

shenzhen beijing guangzhou futian nanshan baoan
shenzhen guangzhou futian beijing nanshan baoan
shenzhen nanshan guangzhou futian beijing baoan

pear apple peach grape dew cherry haw fig marc lemon
pear peach grape apple haw fig dew cherry marc lemon
pear peach haw grape fig dew cherry apple marc lemon
pear peach marc lemon haw grape fig dew cherry apple

C++ 代码

#include <iostream>
using namespace std;
const int N = 1010;
string s[N], temp[N];
int n;

void merge_sort(){
    for (int i = 1; i <= n; i*= 2){
        for (int j = 1; j <= n; j += i*2){
            int l = j, r = j+i, k = 0;
            if (r > n) break;
            int ll = l+i-1, rr = min(r+i-1, n);

            while (l <= ll && r <= rr){
                if (s[l] > s[r]) temp[k++] = s[l++];
                else temp[k++] = s[r++];
            }

            while (l <= ll) temp[k++] = s[l++];
            while (r <= rr) temp[k++] = s[r++];

            for (int x = 0; x < k; ++x) s[j+x] = temp[x];
        }

        for (int k = 1; k<= n; ++k){
            if (k < n) cout << s[k] << " ";
            else cout << s[k] << endl;
        }
    }
}

int main(){
    int t;
    cin >> t;

    while (t--){
        cin >> n;

        for (int i = 1; i <= n; ++i) cin >> s[i];

        merge_sort();
        cout << endl;
    }

    return 0;
}

F. DS内排—堆排序

题目描述
给定一组数据,使用堆排序完成数据的降序排序。(建小顶堆)。

输入
数据个数n,n个整数数据

输出
初始创建的小顶堆序列

每趟交换、筛选后的数据序列,输出格式见样例

输入样例

8 34 23 677 2 1 453 3 7


输出样例

8 1 2 3 7 23 453 677 34
8 2 7 3 34 23 453 677 1
8 3 7 453 34 23 677 2 1
8 7 23 453 34 677 3 2 1
8 23 34 453 677 7 3 2 1
8 34 677 453 23 7 3 2 1
8 453 677 34 23 7 3 2 1
8 677 453 34 23 7 3 2 1

C++ 代码

#include <iostream>
using namespace std;
const int N = 1e5+10;
int n, sz;
int h[N];

void down(int u){
    int t = u;
    if (u*2 <= sz && h[t] > h[2*u]) t = u*2;
    if (u*2+1 <= sz && h[t] > h[2*u+1]) t = u*2+1;

    if (t != u){
        swap(h[t], h[u]);
        down(t);
    }
}

int main(){
    cin >> n;
    sz = n;

    for (int i = 1; i <= n; ++i) cin >> h[i];

    for (int i = n/2; i; --i) down(i);
    cout << n;
    for (int i = 1; i <= n; ++i) cout << " " << h[i];
    cout << endl;

    while (sz > 1){
        swap(h[1], h[sz]);

        sz--;
        down(1);
        cout << n;

        for (int i = 1; i <= n; ++i) cout << " " << h[i];
        cout << endl;
    }

    return 0;
}

G. 基数排序(内部排序)

题目描述
给定一组数据,对其进行基数升序排序。

输入
测试次数t

每组测试数据一行:数字个数n,后跟n个数字(整数)

注:如果序列中有负数,则每个数字加上最小负数的绝对值,使序列中的数均大于等于0。排序后再减去最小负数的绝对值。

输出
对每组测试数据,输出每趟分配、收集的结果。若分配中该位没有数字,输出NULL。具体输出格式见样例。每组测试数据间以空行分隔。

如果序列中有负数,最后输出减去最小负数绝对值的序列值。

输入样例

2
10 278 109 63 930 589 184 505 269 8 83
6 57 0 93 19 18 99

输出样例

0:->930->^
1:NULL
2:NULL
3:->63->83->^
4:->184->^
5:->505->^
6:NULL
7:NULL
8:->278->8->^
9:->109->589->269->^
930 63 83 184 505 278 8 109 589 269
0:->505->8->109->^
1:NULL
2:NULL
3:->930->^
4:NULL
5:NULL
6:->63->269->^
7:->278->^
8:->83->184->589->^
9:NULL
505 8 109 930 63 269 278 83 184 589
0:->8->63->83->^
1:->109->184->^
2:->269->278->^
3:NULL
4:NULL
5:->505->589->^
6:NULL
7:NULL
8:NULL
9:->930->^
8 63 83 109 184 269 278 505 589 930

0:->0->^
1:NULL
2:NULL
3:->93->^
4:NULL
5:NULL
6:NULL
7:->57->^
8:->18->^
9:->19->99->^
0 93 57 18 19 99
0:->0->^
1:->18->19->^
2:NULL
3:NULL
4:NULL
5:->57->^
6:NULL
7:NULL
8:NULL
9:->93->99->^
0 18 19 57 93 99

C++ 代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;
queue<int>res[N];
int nums[N], n, minx, maxn;

void RadixSort(){
    int pow = 1;
    for (int i = 1; i <= maxn; ++i){
        pow *= 10;
        for (int j = 0; j < n; ++j){
            int temp = nums[j]/(pow/10)%10;
            res[temp].push(nums[j]);
        }
        int cnt = 0;
        for (int j = 0; j < 10; ++j){
            cout << j << ":";
            bool flag = false;
            if (!res[j].empty()){
                while (!res[j].empty()){
                    cout << "->" << res[j].front()-minx;
                    nums[cnt++] = res[j].front();
                    res[j].pop();
                }
                cout << "->^" << endl;
            }else {
                cout << "NULL" << endl;
            }
        }
        for (int j = 0; j < n; ++j){
            if (j < n-1) cout << nums[j] << " ";
            else cout << nums[j] << endl;
        }
    }
}

int main(){
    int t;
    cin >> t;

    while (t--){
        cin >> n;
        minx = 0, maxn = 0;

        for (int i = 0; i < n; ++i){
            cin >> nums[i];
            minx = min(minx, nums[i]);
            int temp = abs(nums[i]), cnt = 0;
            while (temp){
                cnt++;
                temp /= 10;
            }
            maxn = max(maxn, cnt);
        }

        if (minx < 0){
            for (int i = 0; i < n; ++i) nums[i] += -minx;
        }

        RadixSort();
        cout << endl;
    }

    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值