1035. 插入与归并(25)

排序算法辨识
本文介绍了一个程序,通过分析排序过程中的中间序列来判断所使用的排序算法是插入排序还是归并排序,并输出下一轮排序后的结果。

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

归并排序进行如下迭代操作:首先将原始序列看成N个只包含1个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下1个有序的序列。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

输入格式:

输入在第一行给出正整数N (<=100);随后一行给出原始序列的N个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。

输出格式:
首先在第1行中输出“Insertion Sort”表示插入排序、或“Merge Sort”表示归并排序;然后在第2行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行末不得有多余空格。

输入样例1:

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0

输出样例1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

输入样例2:

10
3 1 2 8 7 5 9 4 0 6
1 3 2 8 5 7 4 9 0 6

输出样例2:

Merge Sort
1 2 3 8 4 5 7 9 0 6

#include<stdio.h>
#include<malloc.h>
int comp(const void*a,const void*b);
void Display(int a[],int n,int check);
int IsMerge(int a[],int n);
int main()
{
    int n,*a,*b,i,k;
    scanf("%d",&n);
    a=(int *)malloc((n+1)*sizeof(int));
    b=(int *)malloc((n+1)*sizeof(int));
    for(i=1;i<=n;i++)scanf("%d",&a[i]);
    for(i=1;i<=n;i++)scanf("%d",&b[i]);
    int check=IsMerge(b,n);
    if(check)printf("Merge Sort\n");
    else printf("Insertion Sort\n");
    Display(b,n,check);
}
int IsMerge(int a[],int n)
{
    int i,begin=1,step=2;
    while(1)
    {
        for(i=begin;i<(begin+step-1)&&i<n;i++)
        {
            if(a[i]>a[i+1])
            {
                if(step==2)return 0;
                else return step/2;
            }
        }
        begin+=step;
        if(i==n-1||i==n)
        {
            begin=1;
            step*=2;
        }
    }
}
void Display(int a[],int n,int check)
{
    int k,i;
    if(check)
    {
        int begin=1;
        while(begin<n)
        {
            qsort(&a[begin],check*2,sizeof(int),comp);
            begin+=2*check;
            if(begin<n&&(begin+2*check-1)>n)
            {
                qsort(&a[begin],n-begin+1,sizeof(int),comp);
                begin+=2*check;
            }

        }
        for(i=1;i<=n;i++)
        {
            printf("%d",a[i]);
            if(i<n)printf(" ");
        }
    }
    else
    {
        for(i=1;i<=n;i++)
        {
            if(a[i]>a[i+1])
            {
                k=i;break;
            }
        }
        for(i=1;i<=k;i++)
        {
            if(a[i]>a[k+1])
            {
                int temp=a[k+1];
                int j;
                for(j=k+1;j>i;j--)a[j]=a[j-1];
                a[i]=temp;
                break;
            }
        }
        for(i=1;i<=n;i++)
        {
            printf("%d",a[i]);
            if(i<n)printf(" ");
        }
    }
}
int comp(const void*a,const void*b)
{
    return *(int*)a-*(int*)b;
}

转载于:https://www.cnblogs.com/xLester/p/5902190.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值