插入排序还是归并排序

【InsertionSort_MergeSort——PTAques的文件名】

7-1 插入排序还是归并排序

根据维基百科的定义:

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

归并排序进行如下迭代操作:首先将原始序列看成 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

 

思路:实现insertion和merge,每一次迭代和B作一次比较,

如果相等则做标记,再走一轮则停止。【会改变输入的A,所以直接return,但是最先构造两个A,以防验证两次。】

如果不相等,则ans=-1不变,走merge。

merge算法借鉴网上不是很懂,其余注释写在文章中【有一个错误MD找了好TM久】。

#include <iostream>

using namespace std;
//int C[100]={0};
int ans=-1;
void swap(int* A,int j ,int i){
    int temp=A[j];
    A[j]=A[i];
    A[i]=temp;
}
void insertion(int* A, int* B, int n){   //为了每次写完都比较,所以每次迭代完都比较一次
    int flag2=0;
    for (int i=1;i<n;i++){  //第0个可以不用排
        int flag=0;
        for (int j=i;j>0;j--){
            if (A[j]<A[j-1])
                swap(A,j,j-1);
        }


        for (int i=0;i<n;i++){
            if(A[i]!=B[i]){
                flag=1;
                break;
            }
        }

        if (flag2==1){
//           for (int i=0;i<n;i++)
//               C[i] = A[i];
           return; //记录了下一轮,该程序结束
        }
        if (flag==0) {
            ans=1;
            flag2=1;//再进行下一轮
        }
    }

}


void mergeSortHelper(int* A, int head1, int head2, int tail2){
    int tail1 = head2-1, index=0,len=tail2-head1+1,start=head1;
    int temp[len];
    while(head1 <= tail1 || head2 <= tail2){
        if (head1 > tail1)
            temp[index++]=A[head2++];
        else if(head2 > tail2)
            temp[index++]=A[head1++];
        else{
            if(A[head1] <= A[head2])
                temp[index++]=A[head1++];
            else
                temp[index++]=A[head2++];
        }
    }
    for (int i=0;i<len;i++)
        A[start+i]=temp[i];
}

void merge(int* A, int* B, int n){  //迭代法的归并排序,
    //首先将原始序列看成 N 个只包含 1 个元素的有序子序列,然后每次迭代归并两个相邻的有序子序列,直到最后只剩下 1 个有序的序列。
    //网上借鉴,不是很懂????
    int flag2=0;
    for (int step=1; step<=n; step <<= 1){
        int flag=0;
        int offset = step+step;
        for (int index=0;index<n;index+=offset)
            mergeSortHelper(A,index,min(index+step,n-1),min(index+offset-1,n-1));

        for(int i=0;i<n;i++){
            if (A[i]!=B[i]){
                flag=1;
                break;
            }
        }

//        for (int i=0;i<n-1;i++)
//            cout<<A[i]<<" ";
//        cout<<A[n-1]<<endl;

        if (flag2==1){
            return; //又迭代了一轮,故停止。A在此过程中是一直被改变的
        }
        if (flag==0){   //操!!!这里一直写的1,怪不得是错的。只要不等就认定了。
            flag2=1; //在这里相等了
        }
    }

}

int main()
{
    int N;
    cin >> N;
    int A[N],B[N];
    int A1[N];
    for (int i=0;i<N;i++){
        cin >> A[i];
        A1[i] = A[i];
    }
    for (int i=0;i<N;i++)
        cin >> B[i];

    insertion(A1,B,N);
    if (ans!=-1){
        cout<<"Insertion Sort"<<endl;
        for (int i=0;i<N-1;i++)
            cout<<A1[i]<<" ";
        cout<<A1[N-1]<<endl;
    }
    else{//肯定就时merge的情况
        merge(A,B,N);
        cout<<"Merge Sort"<<endl;
        for (int i=0;i<N-1;i++)
            cout<<A[i]<<" ";
        cout<<A[N-1]<<endl;
    }
//    int A[9]={8,6,4,2,9,1,0,-2,5};
//    int B[9]={0};
//    merge(A,B,9);
//    for (int i=0;i<7;i++)
//        cout<<A[i]<<" ";
}

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值