实验13 内部排序


A. DS内排—直插排序

时间限制
1s
内存限制
128MB

题目描述

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

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

输入

数据个数n,n个数据

输出

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

样例查看模式
正常显示
查看格式

输入样例1

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

代码

#include <iostream>

using namespace std;

int main() {
    int n, i, j;
    cin >> n;
    int *a = new int[n + 1];
    for (i = 1; i <= n; i++)
        cin >> a[i];
    for (i = 2; i <= n; i++) {
        if (a[i] < a[i - 1]) {
            a[0] = a[i];
            a[i] = a[i - 1];
            for (j = i - 2; a[0] < a[j]; j--)
                a[j + 1] = a[j];
            a[j + 1] = a[0];
        }
        for (int k = 1; k <= n; k++)
            if (k < n) cout << a[k] << ' ';
            else cout << a[k] << endl;
    }
    delete[]a;
}

B. DS排序–希尔排序

时间限制
1s
内存限制
128MB

题目描述

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

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

输入

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

输出

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

样例查看模式
正常显示
查看格式

输入样例1

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

代码

#include <iostream>

using namespace std;
int n;
int data[100];

void shell_insert(int gap) {
    int i, j;
    for (i = gap + 1; i <= n; i++)
        if (data[i] > data[i - gap]) {
            data[0] = data[i];
            for (j = i - gap; j > 0 && data[0] > data[j]; j -= gap)
                data[j + gap] = data[j];
            data[j + gap] = data[0];
        }
    for (i = 1; i <= n; i++)
        if (i < n) cout << data[i] << ' ';
        else cout << data[i] << endl;
}

int main() {
    int t, i, j;
    cin >> t;
    while (t--) {
        cin >> n;
        for (i = 1; i <= n; i++)
            cin >> data[i];
        int gap = n / 2;
        while(gap!=1)
        {
            shell_insert(gap);
            gap/=2;
        }
        shell_insert(gap);
        cout << endl;
    }
}

C. DS排序–快速排序

时间限制
1s
内存限制
128MB

题目描述

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

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

输入

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

输出

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

样例查看模式
正常显示
查看格式

输入样例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

代码

#include <iostream>

using namespace std;
int n;
int data[100];


int Partition(int low, int high) {
    data[0] = data[low];
    int pi = data[low];
    while (low < high) {
        while (low < high && data[high] >= pi) high--;
        data[low] = data[high];
        while (low < high && data[low] <= pi) low++;
        data[high] = data[low];
    }
    data[high] = data[0];
    int i;
    for (i = 1; i <= n; i++)
        if (i < n) cout << data[i] << ' ';
        else cout << data[i] << endl;
    return high;
}

void Qsort(int low, int high) {
    if (low < high) {
        int pi = Partition(low, high);
        Qsort(low, pi - 1);
        Qsort(pi + 1, high);
    }
}

int main() {
    int t, i, j;
    cin >> t;
    while (t--) {
        cin >> n;
        for (i = 1; i <= n; i++)
            cin >> data[i];
        int low = 1, high = n;
        Qsort(low, high);
        cout << endl;
    }
}

D. DS内排—堆排序

时间限制
1s
内存限制
128MB

题目描述

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

输入

数据个数n,n个整数数据

输出

初始创建的小顶堆序列

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

样例查看模式
正常显示
查看格式

输入样例1

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

代码

#include <iostream>

using namespace std;
int n;
int data[100];

void show()
{
    cout << n<<' ';
    int i;
    for (i = 1; i <= n; i++)
        if (i < n) cout << data[i] << ' ';
        else cout << data[i] << endl;
}
void Heap_update(int pos,int Len) {
    int rc = data[pos];
    int j;
    for (j = 2 * pos; j <= Len; j *= 2) {
        if (j + 1 <= Len && data[j + 1] < data[j]) j++;
        if (rc < data[j]) break;
        data[pos] = data[j];
        pos = j;
    }
    data[pos] = rc;
}

void Heapsort() {
    int i;
    for (i = n / 2; i > 0; i--)
        Heap_update(i,n);
        show();
    for (i = n; i > 1; i--) {
        int tem=data[1];
        data[1]=data[i];
        data[i]=tem;
        Heap_update(1,i-1);
        show();
    }
}

int main() {
    int i, j;
    cin >> n;
    for (i = 1; i <= n; i++)
        cin >> data[i];
    Heapsort();
    cout << endl;

}

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

时间限制
1s
内存限制
128MB

题目描述

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

输入

测试次数t

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

输出

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

样例查看模式
正常显示
查看格式

输入样例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

代码

#include <bits/stdc++.h>

using namespace std;
string str[100];
string TR1[100];
string TR2[100];
int n;

void show(string a[]) {
    int i;
    for (i = 1; i <= n; i++) {
        cout << a[i];
        if (i < n) cout << ' ';
        else cout << endl;
    }
}

void Merge(string s2[], string s1[], int low, int mid, int high) { //链接
    int j, k, i;
    for (j = mid + 1, k = low, i = low; i <= mid && j <= high; k++) {
        if (s2[i] > s2[j]) s1[k] = s2[i++];
        else s1[k] = s2[j++];
    }

    while (i <= mid)
        s1[k++] = s2[i++];
    while (j <= high)
        s1[k++] = s2[j++];
}

void MPass(string input[], string output[], int Leng) {  //分块
    int i = 1;
    while (i + 2 * Leng - 1 <= n) {
        Merge(input, output, i, i + Leng - 1, i + 2 * Leng - 1);
        i += 2 * Leng;
    }
    if ((i + Leng - 1) < n) Merge(input, output, i, i + Leng - 1, n);
    else {
        for (int j = i; j <= n; j++)
            output[j] = input[j];
    }
}

void Merge_Sort() {
    int Len = 1;
    while (Len <= n) {
        MPass(TR2, TR1, Len);
        show(TR1);
        Len *= 2;
        if (Len <= n) {
            MPass(TR1, TR2, Len);
            show(TR2);
            Len *= 2;
        }
    }
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        int i;
        cin >> n;
        for (i = 1; i <= n; i++) {
            cin >> str[i];
            TR1[i] = str[i];
            TR2[i] = str[i];
        }
        Merge_Sort();
        cout << endl;
    }
}

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

时间限制
1s
内存限制
128MB

题目描述

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

输入

测试次数t

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

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

输出

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

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

样例查看模式
正常显示
查看格式

输入样例1

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

代码

#include <bits/stdc++.h>

using namespace std;
int da[100];
int da2[100];
int num;

class Node {
public:
    int data;
    Node *next;

    Node(int a = 0) : data(a), next(NULL) {}
};

class List {
public:
    Node *head;
    int Len;

    List() {
        head = new Node;
        Len = 0;
    }

    void Create(int num) {
        Node *tail = head;
        while (tail->next != NULL)
            tail = tail->next;
        tail->next = new Node(num);

    }

    void show_List() {
        if (head->next == NULL) {
            cout << "NULL" << endl;
            return;
        }
        Node *tem = head->next;
        while (tem) {
            cout << "->" << tem->data;
            tem = tem->next;
        }
        cout << "->^" << endl;
    }
};

void change_data(List p[10]) {
    int i, cnt = 0;
    Node *tem;
    for (i = 0; i <= 9; i++) {
        tem = p[i].head->next;
        while (tem) {
            da[cnt++] = tem->data;
            tem = tem->next;
        }
    }
}

void show_data() {
    int i;
    for (i = 0; i < num; i++) {
        cout << da[i];
        if (i < num - 1) cout << ' ';
        else cout << endl;
    }

}

int Max_wei() {
    int i, max = da2[0];
    for (i = 1; i < num; i++)
        if (max <da2[i]) max = da2[i];
    int k = 0;
    while (max != 0) {
        max /= 10;
        k++;
    }
    return k;
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        int i, k;
        cin >> num;
        for (i = 0; i < num; i++) {
            cin >> da[i];
            da2[i] = da[i];
        }
        int Max_k = Max_wei();
        for (k = 0; k < Max_k; k++) {
            List p[10];
            int Key = pow(10, k);
            for (i = 0; i < num; i++)
                p[da[i] / Key % 10].Create(da[i]);

            for (i = 0; i < 10; i++) {
                cout << i << ':';
                p[i].show_List();
            }
            change_data(p);
            show_data();
        }
        cout<<endl;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值