PTA 09-排序1 排序(附全部算法实现及结果)

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

题目地址:09-排序1 排序(25 分)

题目描述:

给定N个(长整型范围内的)整数,要求输出从小到大排序后的结果。
本题旨在测试各种不同的排序算法在各种数据情况下的表现。各组测试数据特点如下:

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

  • 输入格式:
    入第一行给出正整数N(≤10^​5)随后一行给出N个(长整型范围内的)整数,其间以空格分隔。

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

解题方法:
本博文将会给出以下几种排序算法的代码以及效果

  1. 冒泡排序
  2. 插入排序
  3. 原始的希尔排序
  4. Hibibbard增量序列的希尔排序
  5. Sedgewick增量序列的希尔排序
  6. 堆排序
  7. 递归版的归并排序
  8. 循环版的归并排序

程序:

#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
using namespace std;

void Bubble_sort(long A[], int N)
{   /* 冒泡排序 */
    for (int P = N-1; P >=1; P--)
    {
        int flag = 0;
        for (int i = 0; i < P; i++)
        {
            if (A[i] > A[i+1])
            {
                swap(A[i], A[i+1]);
                flag = 1;
            }
        }
        if (flag == 0)  // 如果一轮循环没有交换位置,就说明是已经有序了
            break;
    }
}

void Insert_sort(long A[], int N)
{   /* 插入排序 */
    int P, i;
    for (P = 1; P < N; P++)
    {
        long temp = A[P];
        for (i = P; i >= 1 && temp < A[i-1]; i--)
            A[i] = A[i-1];
        A[i] = temp;
    }
}

void Shell_sort(long A[], int N)
{   /* 原始的希尔排序 */
    int P, i, D;
    for (D = N/2; D >= 1; D /= 2)
    {
        for (P = D; P < N; P++)
        {
            long temp = A[P];
            for (i = P; i >= D && temp < A[i-D]; i -= D)
                A[i] = A[i-D];
            A[i] = temp;
        }
    }
}

void ShellHib_sort(long A[], int N)
{   /* Hibbard增量序列的希尔排序 */
    int k = log2(N), P, i, D;
    for (D = pow(2, k)-1; D >= 1 && k >= 1; D = pow(2, --k)-1)
    {
        // printf("%d %d\n", k, D);
        for (P = D; P < N; P++)
        {
            long temp = A[P];
            for (i = P; i >= D && temp < A[i-D]; i -= D)
                A[i] = A[i-D];
            A[i] = temp;
        }
    }
}

void ShellSed_sort(long A[], int N)
{   /* Sedgewick增量序列的希尔排序 */
    int D, P, j, i = 0;
    int Sedgewick[] = {3905, 929, 505, 209, 109, 41, 19, 5, 1, 0};
    for (D = Sedgewick[i]; D >= N; D = Sedgewick[i++]);
    for (D = Sedgewick[i]; D > 0; D = Sedgewick[++i])
    {
        for (P = D; P < N; P++)
        {
            long temp = A[P];
            for (j = P; j >= D && temp < A[j-D]; j -= D)
                A[j] = A[j-D];
            A[j] = temp;
        }
    }
}

/***************** 堆排序 **************/
void PrecDown(long A[], int p, int N)
{
    int parent, child;
    long x = A[p];
    for (parent = p; (2*parent+1) < N ; parent = child)
    {
        child = 2*parent + 1;
        if (child != N-1 && A[child+1] > A[child])
            child++;    // 存在右儿子并且右儿子比做儿子大
        if (A[child] < x) 
            break;
        else
            A[parent] = A[child];
    }
    A[parent] = x;
}

void Heap_sort(long A[], int N)
{
    for (int i = N/2; i >= 0; i--)
        PrecDown(A, i, N);  /* 建立堆 */
    for (int i = N-1; i > 0; i--)
    {
        swap(A[0], A[i]);
        PrecDown(A, 0, i);
    }
}
/*************** 堆排序结束 ************/

/**************** 归并排序(递归版) *************/
void Merge(long A[], long temp[], int L, int R, int RightEnd)
{
    int LeftEnd = R - 1;
    int Num = RightEnd - L + 1;
    int temIdx = L, i;
    while (L <= LeftEnd && R <= RightEnd)
    {
        if (A[L] <= A[R])
            temp[temIdx++] = A[L++];
        else
            temp[temIdx++] = A[R++];
    }
    while (L <= LeftEnd)    /* 如果左边部分有多余 */
        temp[temIdx++] = A[L++];
    while (R <= RightEnd)   /* 如果右边部分有多余 */
        temp[temIdx++] = A[R++];
     for( i = 0; i < Num; i++, RightEnd-- )
         A[RightEnd] = temp[RightEnd]; /* 加temp中的元素返回给A */
}

void MSort(long A[], long temp[], int L, int RightEnd)
{
    int center;
    if (L < RightEnd)
    {
        center = (L + RightEnd) / 2;
        MSort(A, temp, L, center);
        MSort(A, temp, center+1, RightEnd);
        Merge(A, temp, L, center+1, RightEnd);
    }
}

void Merge_sort(long A[], int N)
{   /* 归并排序入口程序 */
    long *temp;
    temp = (long*)malloc(N * sizeof(long));
    MSort(A, temp, 0, N-1);
    free(temp);
}
/************** 归并排序结束(递归版) ***********/


/**************** 归并排序(循环版) *************/
void Merge1(long A[], long temp[], int L, int R, int RightEnd)
{
    int LeftEnd = R - 1;
    int temIdx = L;
    while (L <= LeftEnd && R <= RightEnd)
    {
        if (A[L] <= A[R])
            temp[temIdx++] = A[L++];
        else
            temp[temIdx++] = A[R++];
    }
    while (L <= LeftEnd)    /* 如果左边部分有多余 */
        temp[temIdx++] = A[L++];
    while (R <= RightEnd)   /* 如果右边部分有多余 */
        temp[temIdx++] = A[R++];
    /* 与Megre比少了最后一步 */
}

void Merge_pass(long A[], long temp[], int N, int length)
{
    int i, j;
    for (i = 0; i < N-2*length; i += 2*length)  
        Merge1(A, temp, i, i+length, i+2*length-1);
    if (i+length <= N-1)    /* 超过一个子序列 =号必须加*/
        Merge1(A, temp, i, i+length, N-1);
    else    /* 只剩一个子序列不到了 */
        for (j = i; j <= N-1; j++)
            temp[j] = A[j];
}

void Merge_sort1(long A[], int N)
{
    long* temp;
    int length = 1;
    temp = (long*)malloc(N * sizeof(long));
    while (length < N)
    {   /* 这么做A就是排好序的数组 */
        Merge_pass(A, temp, N, length);
        length *= 2;
        Merge_pass(temp, A, N, length);
        length *= 2;
    }
}
/*************** 归并排序结束(循环版) **********/


int main(int argc, char const *argv[])
{
    int N;
    scanf("%d", &N);
    long A[N];
    for (int i = 0; i < N; i++)
        scanf("%ld", &A[i]);
    ShellSed_sort(A, N);
    for (int i = 0; i < N; i++)
    {
        if (i != 0)
            printf(" ");
        printf("%ld", A[i]);
    }
    return 0;
}

运行效果:

  • 冒泡排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • 插入排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • 原始的希尔排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • Hibbard增量序列的希尔排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • Sedgewick增量序列的希尔排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • 堆排序
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • 归并排序递归版
    《PTA 09-排序1 排序(附全部算法实现及结果)》
  • 归并排序循环版
    《PTA 09-排序1 排序(附全部算法实现及结果)》
    原文作者:排序算法
    原文地址: https://blog.csdn.net/Invokar/article/details/80202438
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞