PTA 5-12 排序 (25分)

给定NN个(长整型范围内的)整数,要求输出从小到大排序后的结果。

本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:只有1个元素;
  • 数据2:11个不相同的整数,测试基本正确性;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;
  • 数据6:105个顺序整数;
  • 数据7:105个逆序整数;
  • 数据8:105个基本有序的整数;
  • 数据9:105个随机正整数,每个数字不超过1000。

    输入格式:

    输入第一行给出正整数NN(\le 10^5≤10?5??),随后一行给出NN个(长整型范围内的)整数,其间以空格分隔。

    输出格式:

    在一行中输出从小到大排序后的结果,数字间以1个空格分隔,行末不得有多余空格。

    输入样例:

    11
    4 981 10 -17 0 -20 29 50 8 43 -5
    

    输出样例:

    -20 -17 -5 0 4 8 10 29 43 50 981
  • 下面试验了各种排序算法的的表现

  • 算法/时间复杂度


    10^3的随机整数


    10^4个随机整数


    10^5个随机整数


    10^5个顺序整数


    10^5个逆序整数


    10^5个基本有序的整数


    10^5个随机正整数,每个数不超过1000


    冒泡排序


    4ms


    228ms


    >10s


    88ms


    >10s


    650ms


    >10s


    插入排序


    3ms


    35ms


    4784ms


    82ms


    9206ms


    115ms


    4499ms


    选择排序


    5ms


    332ms


    >10s


    >10s


    >10s


    >10s


    >10s


    归并排序(递归版本)


    4ms


    12ms


    131ms


    82ms


    127ms


    83ms


    75ms


    堆排序


    3ms


    10ms


    103ms


    89ms


    102ms


    126ms


    94ms


    希尔排序


    3ms


    25ms


    128ms


    119ms


    125ms


    117ms


    116ms


    归并排序(循环版本)


    3ms


    24ms


    125ms


    78ms


    99ms


    77ms


    93ms


    快速排序(pivot取中位数)


    3ms


    10ms


    122ms


    76ms


    112ms


    76ms


    69ms

/* 冒泡排序
 * 1.最好情况 已经有序了O(n)
 * 2.最坏情况 逆序 O(n^2)
 * 3.平均情况 O(n^2)
 */
void bubble_sort(int a[],int n) {
    for (int i = n - 1; i > 0; i--) {
        int flag = 0;
        for (int j = 0; j < i; j++) {
            if (a[j] > a[j + 1]) {
                int temp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = temp;
                flag = 1;
            }
        }
        if (flag == 0)
            break;
    }
}
/*
 * 插入排序(对于基本有序的数组排序有较好的表现)
 * 1.最好情况  有序  O(n)
 * 2.最坏情况  逆序  o(n^2)
 * 3.平均情况 O(n^2)
 */
void insertion_sort(int a[],int n) {
    int i, j;
    for (i = 1; i < n; i++) {
        int temp = a[i]; /* 当前要插入的数 */
        for (j = i - 1; j >= 0; j--) {
            if (temp >= a[j])
                break;
            a[j + 1] = a[j];
        }
        a[j + 1] = temp;
    }
}
/*
 * 希尔排序(不稳定)
 * 1.时间复杂度跟取得序列有关系
 * 2.取 n/2,n/2^2,...,1序列时 最坏情况下时间复杂度为O(n^2)
 * 3.sedgewick序列时 最坏: O(n^3/2) 平均:O(n^5/4)
 */
void shell_sort(int a[],int n) {
    int i, j;
    int sedgewick[] = { 929,505,209,41,19,5,1,0 };
    for (i = 0; sedgewick[i] >= n; i++);
    for(int d=sedgewick[i];d>0;d=sedgewick[++i])
        for (int p = d; p < n; p++) {
            int temp = a[p];
            for (j = p; j >= d&&a[j - d] > temp; j -= d)
                a[j] = a[j - d];
            a[j] = temp;
        }
}
/*
 * 选择排序(不稳定 应该是最差的排序算法了吧)
 * 最好 最坏  平均 时间复杂度都是O(n^2)
 */
void  selection_sort(int a[],int n) {
    for (int i = 0; i < n-1; i++) {
        int min = i;
        for (int j = i + 1; j < n; j++) {
            if (a[j] < a[min]) {
                min = j;
            }
        }
        if (min != i) {
            int temp = a[min];
            a[min] = a[i];
            a[i] = temp;
        }
    }
}
/*
 * 归并排序(递归版本) 在外排序中使用较多
 * 1.时间复杂度 最好  最坏 平均 都是O(n*log n).
 * 2.空间复杂度 是 O(n).
 */
void merge1(int a[],int temp[],int left,int right,int rightEnd) {
    int l = left;
    int leftEnd = right -1;
    int r = right;
    int index = rightEnd - left + 1;
    int x = left;
    while (l <= leftEnd && r <= rightEnd) {
        if (a[l] <= a[r]) {
            temp[x++] = a[l++];
        }
        else
            temp[x++] = a[r++];
    }
    while (l <= leftEnd)
        temp[x++] = a[l++];
    while (r <= rightEnd)
        temp[x++] = a[r++];
    for (int i=rightEnd; index > 0; index--,i--)
        a[i] = temp[i];
}

void mSort1(int a[],int temp[],int left,int right) {
    if (left < right) {
        int mid = (left + right) / 2;
        mSort1(a, temp, left, mid);
        mSort1(a, temp, mid + 1, right);
        merge1(a, temp, left, mid + 1, right);
    }

}
void merge_sort1(int a[],int n) {
    int* temp = (int*)malloc(sizeof(int)*n);
    if (temp != NULL ) {
        mSort1(a, temp, 0, n-1);
        free(temp);
    }
    else {
        cout << "内存不足" << endl;
    }
}
/*
 * 归并排序循环版本
 * 1. 时间复杂度  最好 最坏 平均 都为O(n * log n)
 * 2. 空间复杂度O(n)
*/
void merge2(int a[], int temp[], int left, int right, int rightEnd) {
    int l = left;
    int leftEnd = right - 1;
    int r = right;
    int index = rightEnd - left + 1;
    int x = left;
    while (l <= leftEnd && r <= rightEnd) {
        if (a[l] <= a[r]) {
            temp[x++] = a[l++];
        }
        else
            temp[x++] = a[r++];
    }
    while (l <= leftEnd)
        temp[x++] = a[l++];
    while (r <= rightEnd)
        temp[x++] = a[r++];
}

void mergePass(int a[],int temp[],int n,int length) {
    int i;
    for (i = 0; i + 2 * length <= n; i += 2 * length) {
        merge2(a, temp, i, i + length, i + 2 * length - 1);
    }
    if (i + length < n) {
        merge2(a, temp, i, i + length, n - 1);
    }
    else
        for (int j = i; j < n; j++)
            temp[j] = a[j];
}
void merge_sort2(int a[],int n) {
    int* temp = (int*)malloc(n * sizeof(int));
    if (temp != NULL) {
        int length = 1;
        while (length < n) {
            mergePass(a, temp, n, length);
            length *= 2;
            mergePass(temp, a, n, length);
            length *= 2;
        }
        free(temp);
    }
    else {
        cout << "内存不足" << endl;
    }
}
/*
 * 堆排序(不稳定)
 * 最好 最坏 平均 时间复杂度 O(n*log n).
 */
void adjust(int a[],int i, int n) {
    int parent, child;
    int temp = a[i];
    for (parent = i; parent * 2 < n - 1; parent = child) {
        child = parent * 2 + 1; /* 先指向左孩子 */
        if (child != n - 1 && a[child+1] > a[child]) {
            child++; /* 右孩子较大则指向右孩子 */
        }
        if (temp >= a[child])
            break;
        else
            a[parent] = a[child];
    }
    a[parent] = temp;
}
void heap_sort(int a[], int n) {
    for (int i = (n-1) / 2; i >= 0; i--)
        adjust(a,i,n);  /* 构建最大堆 */
    for (int i = n - 1; i > 0; i--) {
        int temp = a[i];
        a[i] = a[0];
        a[0] = temp;
        adjust(a, 0, i);
    }
}
/*
 * 快速排序 (不稳定)
 * 1.最坏情况和主元的选取有一定的关系 如果选首位为主元O(n^2)
 * 2.最好 平均 O(n * log n)
 * 3.当待排元素较少时  快排效率会急速下降  此时可采用插入排序
 */
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}
int median3(int a[],int left,int right) {
    int center = (left + right) / 2;
    if (a[left] > a[center]) {
        swap(&a[left], &a[center]);
    }
    if (a[left] > a[right]) {
        swap(&a[left], &a[right]);
    }
    if (a[center] > a[right]) {
        swap(&a[center], &a[right]);
    }
    swap(&a[center], &a[right-1]); /* 将基准放在数组右端 */
    return a[right-1];
}
void qSort(int a[],int left,int right) {
    int cutoff = 100;
    int low, high, pivot;
    if (right - left >= cutoff) {
        pivot = median3(a, left, right);
        low = left;
        high = right - 1;
        while (1) {
            while (a[++low] < pivot);
            while (a[--high] > pivot);
            if (low < high)
                swap(&a[low], &a[high]);
            else
                break;
        }
        swap(&a[low], &a[right - 1]);
        qSort(a, left, low - 1);
        qSort(a, low + 1, right);
    }
    else
        insertion_sort(a+left,right-left+1);
}

void quick_sort(int a[],int n) {
    qSort(a,0,n-1);
}

算法/时间复杂度


10^3的随机整数


10^4个随机整数


10^5个随机整数


10^5个顺序整数


10^5个逆序整数


10^5个基本有序的整数


10^5个随机正整数,每个数不超过1000


冒泡排序


4ms


228ms


>10s


88ms


>10s


650ms


>10s


插入排序


3ms


35ms


4784ms


82ms


9206ms


115ms


4499ms


选择排序


5ms


332ms


>10s


>10s


>10s


>10s


>10s


归并排序(递归版本)


4ms


12ms


131ms


82ms


127ms


83ms


75ms


堆排序


3ms


10ms


103ms


89ms


102ms


126ms


94ms


希尔排序


3ms


25ms


128ms


119ms


125ms


117ms


116ms


归并排序(循环版本)


3ms


24ms


125ms


78ms


99ms


77ms


93ms


快速排序(pivot取中位数)


3ms


10ms


122ms


76ms


112ms


76ms


69ms


基数排序

 
时间: 2024-10-19 00:38:46

PTA 5-12 排序 (25分)的相关文章

PTA 09-排序1 排序 (25分)

题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/720 5-12 排序   (25分) 给定NN个(长整型范围内的)整数,要求输出从小到大排序后的结果. 本题旨在测试各种不同的排序算法在各种数据情况下的表现.各组测试数据特点如下: 数据1:只有1个元素: 数据2:11个不相同的整数,测试基本正确性: 数据3:103个随机整数: 数据4:104个随机整数: 数据5:105个随机整数: 数据6:105个顺序整数: 数据7:105个逆序整数

PTA - - 06-图1 列出连通集 (25分)

06-图1 列出连通集   (25分) 给定一个有NN个顶点和EE条边的无向图,请用DFS和BFS分别列出其所有的连通集.假设顶点从0到N-1N−1编号.进行搜索时,假设我们总是从编号最小的顶点出发,按编号递增的顺序访问邻接点. 输入格式: 输入第1行给出2个整数NN(0<N\le 100<N≤10)和EE,分别是图的顶点数和边数.随后EE行,每行给出一条边的两个端点.每行中的数字之间用1空格分隔. 输出格式: 按照"{ v_1v?1?? v_2v?2?? ... v_kv?k?? 

PTA 旅游规划(25 分)

7-10 旅游规划(25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 输入格式: 输入说明:输入数据的第1行给出4个正整数N.M.S.D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N?1):M是高速公路的条数:S是出发地的城市编号:D是目的地的城市编号.随后的M行中,每行给出一条高速公路的信息,分别

【PTA】L2-009 抢红包 (25分)

k看了一遍老番茄的烂俗笑话,来整理一下这一道题,与其说是整理,不如说是碰巧做了出来. 在这道题中,我了解到的是algorithm标准函数库中的sort函数,可以用来根据结构体的不同变量对结构体进行排序.在此题中明确要求的是:先对总金额递减排序,如果总金额相同再对红包个数递减排序,如果红包个数还相同的话最后的区分给了编号递增排序. 在这道题中我使用的是结构体Player,定义了全局变量Player player[10000],在主函数中对player[10000]的数据进行运算. 结构体的情况:

PTA 5-15 PAT Judge (25分)

/* * 1.主要就用了个sort对结构体的三级排序 */ #include "iostream" #include "algorithm" using namespace std; int perfectScore[6]; struct Node { int id; int score[6] = {-2,-2,-2,-2,-2,-2}; /* 记录每一题的分数 初始化为-2代表没答题 */ int totalScore = 0; /* 记录总分 */ int pe

【PTA】L2-001 紧急救援 (25分)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图. 在地图上显示有多个分散的城市和一些连接城市的快速道路. 每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上. 当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队.输入格式: 输入第一行给出4个正整数N.M.S.D,其中N(2≤N≤500)是城市的个数 顺便假设城市的编号为0 ~ (N−1):M是快速道路的条数:S是出发地的城市编号:D是目的地的城市编号. 第二行

PTA 10-排序6 Sort with Swap(0, i) (25分)

题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/678 5-16 Sort with Swap(0, i)   (25分) Given any permutation of the numbers {0, 1, 2,..., N-1N?1}, it is easy to sort them in increasing order. But what if Swap(0, *) is the ONLY operation that is

PTA 10-排序5 PAT Judge (25分)

题目地址 https://pta.patest.cn/pta/test/16/exam/4/question/677 5-15 PAT Judge   (25分) The ranklist of PAT is generated from the status list, which shows the scores of the submissions. This time you are supposed to generate the ranklist for PAT. Input Spe

PTA数据结构与算法题目集(中文) 7-35 城市间紧急救援 (25 分)

PTA数据结构与算法题目集(中文)  7-35 城市间紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队. 输入格式: 输入第一行给出4个正整数N.M.S.D,其中N(2)是城市的个数,顺便假设城市的编号为0 ~ (:M是快速道路的条数