首页 > 试题广场 >

插入与归并(25)

[编程题]插入与归并(25)
  • 热度指数:8425 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
根据维基百科的定义:

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

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

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

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


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

输入

10<br/>3 1 2 8 7 5 9 4 6 0<br/>1 2 3 7 8 5 9 4 6 0

输出

Insertion Sort<br/>1 2 3 5 7 8 9 4 6 0
#include <algorithm>
#include <iostream>
using namespace std;
int n,a[110],s[110];
void mergesort(int (&a)[110],int s[],int n){   //注意引用数组的写法
    int step=1,flag=1;
    while(flag){                               //flag表示数组的中间步骤是否与中间数组相同
        flag=0;
        for(int i=0;i<n;i++){
            if(a[i]!=s[i])
                flag=1;
        }
        step*=2;                              //不断的归并排序,直到与中间数组相同,再排序一次并退出
        for(int i=0;i<n;i+=step)
            sort(a+i,a+min(i+step,n));        //不像插入排序一样只用一次处理。是因为判断归并的有序 区间大小比较复杂
    }
}
int main(){
    int i,j;
    cin>>n;
    for(i=0;i<n;i++)
        cin>>a[i];
    for(i=0;i<n;i++)
        cin>>s[i];
    for (i = 0; i < n - 1 && s[i] <= s[i + 1]; i++);  //找出中间数组的有序部分
    for (j = i + 1; a[j] == s[j] && j < n; j++);      //判断排序类型
    if(j==n){
        cout<<"Insertion Sort"<<'\n'; 
        sort(a,a+i+2);                      //直接用sort函数代替插入排序(注意下标)       
    }
    else{
        cout<<"Merge Sort"<<'\n';
        mergesort(a,s,n);
    }
    for(int i=0;i<n;i++){
        cout<<a[i];
        if(i!=n-1) cout<<" ";
    }
    return 0;
}
编辑于 2018-02-11 01:42:20 回复(2)
import java.util.Scanner;
import java.util.Arrays;
public class No1025 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] a = new int[n];//原始的
		int[] b = new int[n];//部分排序过的
		for(int i = 0;i<n;i++)
			a[i] = in.nextInt();
		for(int i = 0;i<n;i++)
			b[i] = in.nextInt();
		String type = "Insertion Sort";
		int index = 0;
		for(int i = 0;i<n-1;i++){
			if(b[i]>b[i+1]){
				index = i+1;//从i+1这里开始无序
				break;
			}
		}
		for(int i = index;i<n;i++){
			if(a[i]!=b[i]){
				type = "Merge Sort";//如果是插入排序,从index开两个数组的顺序是一样的
				break;
			}
		}
		if(type.equals("Insertion Sort")){
			int num = b[index];
			for(int j = index;j>0;j--){
				if(b[j]<b[j-1]){
					b[j] = b[j-1];
					b[j-1] = num;
				}
			}
		}else{
			//如果是归并排序 index的值表示这么多的规模已经排序完,
			//比如index==2 说明规模为2的已经排序完 下一次排序规模为4 
			index = 2*index;
			for(int i = 0;i<n;i+=index){
				int next = i+index>n?n:i+index;
				Arrays.sort(b,i,next);
			}
		}
		System.out.println(type);
		for(int i = 0;i<n-1;i++)
			System.out.print(b[i]+" ");
		System.out.print(b[n-1]);
	}
}

发表于 2016-06-13 15:55:23 回复(5)

PAT_B插入与归并

的测试用例有问题


10

3 1 2 8 7 5 9 4 6 0

1 2 3 5 7 8 9 4 6 0

已排序部分既有可能是


1 2 3 5 7 8

也有可能是


1 2 3 5 7 8 9

会造成多解

发表于 2017-02-13 20:01:12 回复(11)
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void main() {
	int N,next = 0;
	cin >> N;
	vector<int> org,cur;
	enum property{insert,merge}pro = insert;
	for(int i = 0; i < N; ++i)
                cin >> org[i];
	for(int i = 0; i < N; ++i)
                cin >> cur[i];
	for(unsigned int i = 1; i < cur.size(); ++i) {
		if(cur[i] < cur[i-1]) {
			next = i;
			for(; i < cur.size(); ++i) {
				if(cur[i] != org[i]) {//走到这里,说明就是归并了
					pro = merge;
					break;
				}
			}
		}
		if(pro == merge)
		    break;
	}
	if(pro == insert) {
		cout << "Insertion Sort" << endl;
		for(unsigned int i = 0; i < cur.size(); ++i) {
			if(cur[i] < cur[next])
				cout << cur[i] << " ";
			else {
				cout << cur[next] << " ";
				vector<int>::iterator it = cur.begin() + next;
				cur.erase(it);
				for(;i < cur.size(); ++i) {
					cout << cur[i];
					if(i != cur.size() - 1)
						cout << " ";
				}
			}
		}
	}else {
		cout << "Merge Sort" << endl;
		for(unsigned int i = 0; i < cur.size() / (next * 2); ++i)
			sort(cur.begin() + i*next*2, cur.begin() + i*next*2 + next*2);
		for(unsigned int i = 0; i < cur.size(); ++i) {
			cout << cur[i];
			if(i != cur.size() - 1)
				cout << " ";
		}
	}
}

编辑于 2015-11-19 18:04:27 回复(1)
import java.util.Arrays;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int n=in.nextInt();
		int a[]=new int[n];
		int b[]=new int[n];
		for (int i=0;i<n;i++){
			a[i]=in.nextInt();
		}
		for (int i=0;i<n;i++){
			b[i]=in.nextInt();
		}
		
		Boolean f=false;
		int index=0;
		while(b[index+1]>=b[index]){
			index++;
		}
		for(int j=index+1;j<n;j++){
			if(a[j]!=b[j]){
				f=true;
				break;
			}
		}
		
		if(!f){
			System.out.println("Insertion Sort");
			int j=index;
			int i=b[index+1];
			while(j>=0&&b[j]>i){
				b[j+1]=b[j];
				j--;
			}
				b[j+1]=i;
				
		}else{
			System.out.println("Merge Sort");
			index=(index+1)*2;
			int k=0;
			for(;k+index<n;k+=index){
				Arrays.sort(b,k,k+index);
			}
			Arrays.sort(b,k,n);
			
		}
		for(int k=0;k<n;k++){
			System.out.print(k==0?b[0]:" "+b[k]);
		}
	}

}


发表于 2016-10-21 18:43:36 回复(0)

跟大家分享一下我用列表生成式特性所做的解法。。
# -*- coding:utf-8 -*-

N = raw_input()
lst_1 = map(int, raw_input().split()) #UnSorted
lst_2 = map(int, raw_input().split()) #Sorted

tc1 = [1, 2, 3, 7, 8, 5, 9, 4, 6, 0]
tc2 = [1, 3, 2, 8, 5, 7, 4, 9, 0, 6]
tc3 = [7,8,9,10,2,3,4,5]
tc4 = [5,2]
#---------------------------------------

def isSorted(inlst,i,j):
	# Check inlst[i,j)
	out = True
	# print "isSorted(inlst,%d,%d)"%(i,j)
	for i in range(i,min(j-1, len(inlst)-1)):
		if inlst[i] > inlst[i+1]:
			out = False
			break
	return out

# print isSorted([1,2,3,4],0,4)

def findUnsorted(inlst, i):
	# Check inlst[i:]'s first unsorted element's index.
	# If all sorted, return len(lst)
	allSorted = True
	for i in range(i,len(inlst)-1):
		if inlst[i] > inlst[i+1]:
			allSorted = False
			return i+1
	if allSorted:
		return len(inlst)


# ------------------List Generator---------------------
def mergeState(inlst):
	mergeStep = [pow(2,i) for i in range(1, len(inlst)) if pow(2,i) <= len(inlst)]
	mergeState = [[isSorted(inlst,i,i+step) for i in range(0,len(inlst),step)] for step in mergeStep]
	return mergeState

def nextMerge(inlst, num):
	lstToMerge = [inlst[i:min(i+pow(2,num),len(inlst))] for i in range(0,len(inlst),pow(2,num))]
	out = []
	for lst in lstToMerge:
		out = out + sorted(lst)
	return out

def allTrue(inlst):
	return not (False in inlst)

def isMerge(inlst):
	# inlst: type of mergeState
	# if idx == 0, it's not mergeSort
	for idx, lst in enumerate(inlst):
		if allTrue(lst):
			pass
		else:
			return idx

def isMerge_capped(inlst):
	return isMerge(mergeState(inlst))

# ------------------List Generator---------------------

# print isMerge_capped(tc1)
# print isMerge_capped(tc2)

def inSert(inlst, hi):
	# Aim to insert[hi]
	inlst[0:hi+1] = sorted(inlst[0:hi+1])
	return inlst

if isMerge_capped(lst_2) == 0:
	print "Insertion Sort"
	print str(inSert(lst_2, findUnsorted(lst_2,0))).strip('[]').replace(', ', ' ')
else:
	print "Merge Sort"
	print str(nextMerge(lst_2, isMerge_capped(lst_2)+1)).strip('[]').replace(', ', ' ')

发表于 2016-09-08 00:05:32 回复(0)
有人可以告诉我第四个是测试什么吗,出错了
N = int(input())
m = list(map(int, input().split()))
n = list(map(int, input().split()))
M = m[:]
flag = 1
step = 1
for i in range(1, N):
    t = i
    if n == m:
        print('Insertion Sort')
        while t >= 1:
            if m[t] < m[t-1]:
                m[t], m[t - 1] = m[t-1], m[t]
                t -= 1
            else:
                break
        for i in m:
            print(i, end=' ')
        break
    while t >= 1:
        if m[t] < m[t-1]:
            m[t], m[t-1] = m[t-1], m[t]
            t -= 1
        else:
            break
    if i == N - 1:
        print('Merge Sort')
        while flag:
            flag = 0
            for j in range(0, N):
                if n[j] != M[j]:
                    flag = 1
                    break
            step *= 2
            for z in range(0, N, step):
                M[z: min(z+step, N)] = sorted(M[z: min(z+step, N)])
        for i in M:
            print(i, end=' ')
        break

发表于 2021-07-07 20:52:27 回复(1)
#include <iostream>
#include <memory.h>

using namespace std;

const int maxn = 100;

int orgin[maxn] = {0};
int target[maxn] = {0};
int ins[maxn] = {0};
int mer[maxn] = {0};

bool checkSame(int *a1, int *a2, int n) {
    for (int i = 0; i < n; i++) {
        if (a1[i] != a2[i]) {
            return false;
        }
    }
    return true;
}

void printArray(int *a, int n) {
    for (int i = 0; i < n; i++) {
        if (i == 0) {
            cout << a[i];
        } else {
            cout << " " << a[i];
        }
    }
}


bool checkInsert(int n) {
    int index = 0;
    bool finish = false;
    while(index < n) {
        int cur = ins[index];
        int i;
        for (i = 0; i < index; i++) {
            if (ins[i] > cur) {
                for (int j = index - 1; j >= i; j--) {
                    ins[j + 1] = ins[j];
                }
                ins[i] = cur;
                break;
            }
        }
        if (i == index) {
            index++;
            continue;
        }

        if (finish) {
            cout << "Insertion Sort" << endl;
            printArray(ins, n);
            return true;
        }

        if (checkSame(ins, target, n)) {
            finish = true;
        }

        index++;
    }
    return false;
}

void Merge(int *r, int *r1, int s, int m, int t) {
    int i = s;
    int j = m + 1;
    int k = s;
    while (i <= m && j <= t) {
        if (r[i] < r[j]) {
            r1[k++] = r[i++];
        } else {
            r1[k++] = r[j++];
        }
    }
    if (i <= m) {
        while (i <= m) {
            r1[k++] = r[i++];
        }
    }

    if (j <= t) {
        while (j <= t) {
            r1[k++] = r[j++];
        }
    }
}

void MergePass(int *r, int *r1, int n, int h) {
    int i = 0;
    while (i + 2 * h - 1 < n) {
        Merge(r, r1, i, i + h - 1, i + 2 * h - 1);
        i += 2 * h;
    }
    if (i + h < n) {
        Merge(r, r1, i, i + h - 1, n);
    } else {
        for (int j = i; j < n; j++) {
            r1[j] = r[j];
        }
    }
}

bool checkMerge(int n, int *r) {
    int h = 1;
    int r1[maxn] = {0};
    bool finish = false;
    while (h < n) {
        MergePass(r, r1, n, h);
        h = 2 * h;

        for (int i = 0; i < n; i++) {
            r[i] = r1[i];
        }

        memset(r1, 0, n * sizeof(int));

        if (finish) {
            cout << "Merge Sort" << endl;
            printArray(r, n);
            return true;
        }

        if (checkSame(r, target, n)) {
            finish = true;
        }
    }
    return false;
}

int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) {
        int data;
        cin >> data;
        orgin[i] = data;
        ins[i] = data;
        mer[i] = data;
    }

    for (int i = 0; i < n; i++) {
        cin >> target[i];
    }

    checkInsert(n);
    checkMerge(n, mer);
    return 0;
}
写了个归并排序的博客,如果上面代码太干可以参考~
编辑于 2020-09-17 16:31:37 回复(0)
这题最麻烦的地方在于判断完了是归并排序后,在进行一次排序,由于归并排序的有序区很复杂,不好直接确定,所以我对原来数组(第一个输入的数组)进行归并排序按1 2 4 8 的间隔排,并在每次对比2数组是否完全一致,如果完全一致就再排一次就行。挺麻烦的。😅
import java.util.*;

public class Main{
	static int swi = 1;
    public static void main(String [] args){
        Scanner sc = new Scanner(System.in); 
        int n = sc.nextInt();
        int k = 0;
        boolean flag = true;
        int [] arr = new int [n];
        int [] sortArr = new int [n];
        for(int i = 0; i < n; i++)
        	arr[i] = sc.nextInt();
        for(int i = 0; i < n; i++)
        	sortArr[i] = sc.nextInt();
        for(int i = 1; i < n; i++){
        	if(sortArr[i - 1] > sortArr[i]){
        		k = i;
        		break;
        	}
        }
        for(int i = k; i < n; i++){
        	if(arr[i] != sortArr[i]){
        		flag = false;
        		break;
        	}
        }
        if(flag)
        	insertionSort(sortArr, k);
        else{ 
        	int [] t = new int[arr.length];
        	for(int i = 1; i < n && swi != 0; i <<= 1, i++,swi++){
        		for(int j = 0; j < n; j += i + 1){
        			if(j + i > n)
        				sort(arr,j, n - 1,t);
        			else
        				sort(arr,j, j + i,t);
        		}
        		boolean f = check(arr, sortArr);
         		if(f) swi = -2;
        	}
        	System.out.println("Merge Sort");
        	for(int i = 0; i < arr.length - 1; i++)
    			System.out.print(arr[i] + " ");
    		System.out.print(arr[sortArr.length - 1]);
        }
    }
   private static boolean check(int[] arr, int[] sortArr) {
	   for(int k = 0 ;k < sortArr.length; k++){
			if(arr[k] != sortArr[k])return false;
		}
		return true;
	}
private static void sort(int[] arr, int start, int end, int[] temp) {
	    int i = start, j = (start + end) / 2 + 1;
		int m = (start + end) / 2, n = end;
		int k = 0;
		while (i <= m && j <= n)
		{
			if (arr[i] <= arr[j])
				temp[k++] = arr[i++];
			else
				temp[k++] = arr[j++];
		}
		
		while (i <= m)
			temp[k++] = arr[i++];
		
		while (j <= n)
			temp[k++] = arr[j++];
		
		for (i = 0; i < k; i++)
			arr[start + i] = temp[i];

		
	}
	private static void insertionSort(int[] sortArr, int k) {
		int v = sortArr[k];
		int i = k;
		while(i > 0){
			if(sortArr[i - 1] > v) sortArr[i] = sortArr[i - 1];
			else break;
			i--;
		}
		sortArr[i] = v;
		System.out.println("Insertion Sort");
		for(i = 0; i < sortArr.length - 1; i++)
			System.out.print(sortArr[i] + " ");
		System.out.print(sortArr[sortArr.length - 1]);
	}
}


发表于 2019-08-22 20:25:29 回复(1)
#include<stdio.h>
#include<stdlib.h>
void printList(int list[],int len){
	int i;
	for(i=0;i<len-1;i++)
	    printf("%d ",list[i]);
    printf("%d\n",list[i]);
}
int	compareVec(int list1[],int list2[], int len){
	for(int i=0;i<len;i++)
	    if(list1[i]!=list2[i]) return 0;
    return 1;
} 
void MergeSortedVec(int list[],int low, int median, int high){
	int tempList[high-low+1];
	int i=low,j=median+1,k=0;
	while(i<=median && j<=high){
		 if(list[i]>list[j])
 			tempList[k++] = list[j++];
	     else
	        tempList[k++] = list[i++];}
    if(i<=median)
       while(i<=median)
	      tempList[k++] = list[i++];
    if(j<=high)
       while(j<=high)
          tempList[k++] = list[j++];
    for(i=low,k=0;i<=high;i++,k++)
          list[i] = tempList[k];          
}
int MergeSort(int list[],int len, int referVec[]){
	int low,subLen,i;
	subLen=1;
	i=0;
	while(subLen<len){
          low=0;
		  while(low+subLen<=len){
  			  if(low+2*subLen<len){
  			  	MergeSortedVec(list,low,low+subLen-1,low+2*subLen-1);
  			  }else{
  			  	MergeSortedVec(list,low,low+subLen-1,len-1);
  			  }
  			  low+=2*subLen;
  		   }
  		   if(i==0){
  		     if(compareVec(list,referVec,len)) i=1;}
	          else{
	       	     if(compareVec(list,referVec,len)==0){
		         printf("Merge Sort\n");
                         printList(list,len);
			 return 1;}
		   }	         
		   subLen*=2;		
	}
	return 0;
}
int insertSort(int list[],int len, int referVec[]){
	 int temp,i,j,k;
	 k=0;
	 for(i=1;i<len;i++){
 		temp=list[i];
 		for(j=i-1;list[j]>temp && j>=0;j--)
		 	list[j+1]=list[j];
	 	list[j+1]=temp;
	 	if(k==0){
	 	   if(compareVec(list,referVec,len)) k=1;}
        else{
        	if(compareVec(list,referVec,len)==0){
		         printf("Insertion Sort\n");
                 printList(list,len);
			     return 1;}
        }
 	}
 	return 0;
}

int main(){
	int *list1,*list2,*templist,i,n;
	scanf("%d",&n);
	list1=(int *)malloc(n*sizeof(int));
	list2=(int *)malloc(n*sizeof(int));
	templist=(int *)malloc(n*sizeof(int));
	for(i=0;i<n;i++)
	   {scanf("%d",list1+i);templist[i]=list1[i];}
        for(i=0;i<n;i++)
           scanf("%d",list2+i);
        if(MergeSort(list1,n,list2)) return 0;
	if(insertSort(templist,n,list2)) return 0; 
        printf("no sort find!\n"); 
}

发表于 2016-09-06 13:21:31 回复(0)
#include<iostream>
#include<cstdio>
#include<fstream>
#include<algorithm>
using namespace std;
int main()
{
	int n,i,j,k=1,c,pan=1,is=0,q;
	int a[100],b[100],m[100];
//	fstream inFile;
//	inFile.open("data1035.txt",ios::in);
//	inFile>>n;
	cin>>n;
	for(i=0;i<n;i++)
	{
//		inFile>>a[i];
		cin>>a[i];
		m[i]=a[i];
		//		cout<<a[i]<<" ";
	}
	//	for(i=0;i<n;i++)
	
	for(i=0;i<n;i++)
	{
	//	inFile>>b[i];
		cin>>b[i];
		//		cout<<b[i]<<" ";
	}
	for(;k<n;)
	{
		k=k*2;
		pan=1;
		for(j=0;j<n;j=j+k)
		{
			if(j+k<=n)
				sort(a+j,a+j+k);
			else
				sort(a+j,a+n);
		}
		for(c=0;c<n;c++)
		{
			if(a[c]!=b[c])
			{
				pan=0;
				break;
			}
		}
		if(pan==1)
		{
			is=1;
			k=k*2;
			for(j=0;j<n;j=j+k)
			{
				if(j+k<=n)
					sort(a+j,a+j+k);
				else
					sort(a+j,a+n);
			}
			printf("Merge Sort\n");
			for(c=0;c<n;c++)
			{
				cout<<a[c];
				if(c!=n-1)
					cout<<" ";
			}
			break;
		}
	}
	if(is==0)
	{
		
		for(q=1;q<n;q++)
		{
			pan=1;
			sort(m,m+q);
			for(i=0;i<n;i++)
				if(m[i]!=b[i])
					pan=0;
				if(pan==1)
				{
					cout<<"Insertion Sort"<<endl;
					sort(m,m+q+1);
					for(i=0;i<n;i++)
					{
						cout<<m[i];
						if(i!=n-1)
							cout<<" ";
					}
				}
				if(pan==1)
				{
				//	q=n+1;
					break;
				}
		}
	}
//	cout<<endl;
	return 0;
}
对应输出应该为:
Insertion Sort
1 2 3 4 5 7 8 9 6 0

你的输出为:

Insertion Sort
1 2 3 5 7 8 9 4 6 0
Q
这个错误应该怎么改

发表于 2016-07-05 10:01:45 回复(1)
也是疯了,思路跟第一名的几乎一模一样,可是自己的代码在一个测试用例一直超时。用第一的一试又过了,真是囧死了...
//这是自己的代码..在vs跑没问题..
#include <stdio.h>
#include <algorithm>
using namespace std;
int arr[101] = { 0 };
int brr[101] = { 0 };
int main(){
int n;
scanf("%d", &n);
for (int i = 0; i < n; ++i){
scanf("%d", &arr[i]); 
}
for (int i = 0; i < n; ++i){
scanf("%d", &brr[i]);
}
int i = 1;
while (i < n&&brr[i] >= brr[i - 1]){
++i;
}
int j = i;
while (i < n&&arr[i]==brr[i]){
++i;
}
if (i == n){
printf("Insertion Sort\n");
int tmp = brr[j];
while (j>=0){
if (tmp < brr[j - 1]){
brr[j] = brr[j - 1];
--j;
}
else{
break;
}
}
if (j != -1){
brr[j] = tmp;
}
else{
brr[0] = tmp;
}
for (int k = 0; k < n; k++){
printf("%d%c", brr[k], k == n - 1 ? '\n' : ' ');
}
}
else{
printf("Merge Sort\n");
int i = 1;
int *start;
int *end;
while (true){
bool equal = true;
for (int k = n-1; k >= 0; --k){
if (arr[k] != brr[k]){
equal = false;
break;
}
}
if (equal){
break;
}
    start = &arr[0];
end = &arr[n - 1];
while (start < end){
sort(start, min(start + i, end));
start += i;
}
i <<= 1;
}
start = &arr[0];
end = &arr[n - 1];
while (start < end){
sort(start, min(start + i, end));
start += i;
}
for (int i = 0; i < n; ++i){
printf("%d%c", arr[i], i == n - 1 ? '\n' : ' ');
}
}
system("pause");
return 0;
}

发表于 2015-06-17 17:56:10 回复(0)
#include <stdio.h>
#include <stdlib.h>
 
//int insertion_sort(int*, int*, int);
int cmp(const void* a, const void* b)
{
    return (*(int *)a - *(int *)b);
}
 
void merge_sort(int*, int*, int);
 
int main()
{
    int a[100] = {0}, b[100] = {0};
    int n, i, j;
    scanf("%d", &n);
    for(i = 0; i < n; i++)
        scanf("%d", a + i);
    for(i = 0; i < n; i++)
        scanf("%d", b + i);
    for(i = 0; i < n - 1 && b[i] < b[i + 1]; i++);//排除掉有序的部分
    for(j = i + 1; j < n && a[j] == b[j]; j++);   //判断剩下的部分是否与原部分相同
    if(j == n)
    {
        printf("Insertion Sort\n");
        qsort(a, i + 2, sizeof(int), cmp);
    }
    else
    {
        printf("Merge Sort\n");
        merge_sort(a, b, n);
    }
    for(i = 0; i < n; i++)
    {
        if(i == 0)
            printf("%d", a[i]);
        else
            printf(" %d", a[i]);
    }
    printf("\n");
 
    return 0;
}
 
void merge_sort(int a[], int b[], int n)
{
    int step = 1, flag = 1, tmp, i;
    while(flag)
    {
        flag = 0;
        for(i = 0; i < n; i++)
        {
            if(a[i] != b[i])
                flag = 1;
        }
        step *= 2;
        for(i = 0; i < n; i += step)
        {
            if(i + step > n)//若归并时step的范围超出数组有值的部分,则调整step
            {
                tmp = step;
                step = n - i;
            }
            qsort(a + i, step, sizeof(int), cmp);
            if(i + tmp > n)//将step恢复至原来的值
            {
                step = tmp;
            }
        }
    }
}

编辑于 2020-03-07 13:27:50 回复(0)
标准的归并排序用的是递归,但递归并不适用于这种拆分的情形,就很繁琐
#include<iostream>
using namespace std;
void insert(int R[], int m, int n)  //从m处进行一趟插入排序 
{
    int j;
    int temp;
    temp = R[m];
    j = m-1;
    while(temp < R[j] && j >= 0)
    {
        R[j+1] = R[j];
        j--; 
    }
    R[j+1] = temp;
}
void merge(int R[], int low,int high)  //一次归并
{
    int B[102];
    int i, j ,k;
    int mid = (low + high) / 2;
    for(i = low; i <= high; i++)
        B[i] = R[i];
    for(i = low,j = mid + 1,k = low;i <= mid && j <= high;){
        if(B[i] < B[j])
            R[k++] = B[i++];
        else 
            R[k++] = B[j++];
    }    
    while(i <= mid)        R[k++] = B[i++];
    while(j <= high)    R[k++] = B[j++];
}
bool cmp(int R[],int B[],int n)  //比较两数组是否相同
{
    for(int i = 0; i < n; i++)
        if(R[i] != B[i])
            return false;
    return true;
} 
int main()
{
    int i,j,n;
    int arr[102],brr[102];
    int is_insert = true;
    cin >> n;
    for(i = 0; i < n;i++)    cin >> arr[i];
    for(i = 0; i < n;i++)    cin >> brr[i];
    for(i = 0; brr[i] <= brr[i+1] && i < n; i++){}
    j = i + 1;  //对插排而言,j指向将要插入的元素
    for(i = j; i<n ;i++){
        if(brr[i] != arr[i]){
            is_insert = false;
            break;
        }
    }
    if(is_insert){
        cout << "Insertion Sort" << endl;
        insert(brr, j, n);
        for(i = 0; i < n; i++)
            cout << brr[i] << " ";
    }
    else{
        cout << "Merge Sort" << endl;
        float step = 1;
        while(!cmp(arr,brr,n)){//循环到两数组相等
            step *= 2;
            i = j = 0;
            while(j < n-1 && i < n){
                j = (i+step-1)>n-1 ? n-1 : i+step-1;
                merge(arr,i,j);
                i = i + step;
            }
        }
        step *= 2;  //最后再归并一轮
        i = j = 0;
        while(j < n-1 && i < n){
            j = (i+step-1)>n-1 ? n-1 : i+step-1;
            merge(arr,i,j);
            i = i + step;
        }
        for(i = 0; i < n; i++)
            cout << arr[i] << " ";
    }
} 


发表于 2020-01-15 22:51:43 回复(0)
这道题的归并和我理解的归并排序略有出入。。不过好像用传统的归并排序很难完成此题,因此归并排序逻辑使用评论中的一种方法,代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

int comp(const void *a, const void *b)
{
    return *(int*)a - *(int*)b;
}

void swap_int(int *a, int *b)
{
    *a = *a ^ *b;
    *b = *a ^ *b;
    *a = *a ^ *b;
}

bool compare_array(int *a, int *target, int len)
{
    for(int i = 0; i < len; i++)
    {
        if(a[i] != target[i]) return false;
    }
    return true;
}

void print_array(int a[], int len)
{
    int i;
    for( i = 0; i < len; i++)
        printf("%d%c", a[i], (i == len - 1) ? '\n' : ' ');
}

bool insert_sort(int a[], int target[], int len)
{
    int i, j, tmp, flag = 0;
    for( i = 1; i < len; i++)
    {
        tmp = i;
        for( j = i - 1; j >= 0; j--, tmp--)
        {
            if(a[tmp] < a[j]) swap_int(&a[tmp], &a[j]);
            else break;
        }
        if(compare_array(a, target, len))
        {
            flag = 1;
            continue;
        }
        if(flag) return true;
    }
    return false;
}

int main(void)
{
    int i, j, n, a[100], a1[100], b[100];
    scanf("%d", &n);
    for( i = 0; i < n; i++)
    {
        if( i == n - 1 ) scanf("%d", &a[i]);
        else scanf("%d ", &a[i]);
        a1[i] = a[i];
    }
    for( i = 0; i < n; i++)
    {
        if( i == n - 1) scanf("%d", &b[i]);
        else scanf("%d ", &b[i]);
    }
    if(insert_sort(a1, b, n))
    {
        printf("Insertion Sort\n");
        print_array(a1, n);
    }
    else{
        int length;
        printf("Merge Sort\n");
        for(length = 1, i = 0; i < n && length <= n; length *= 2)
        {
            for(i = 0; i < n && a[i] == b[i]; i++) ;
            for(j = 0; j < n / length; j++)
                qsort(a + j * length, length, sizeof(int), comp);
            qsort(a + j * length, n % length, sizeof(int), comp);
        }
        print_array(a, n);
    }
    return 0;
}


发表于 2019-12-18 15:17:13 回复(0)
#include <stdio.h>
#include <stdlib.h>
int comp(const void *a, const void *b){
    return *(int*)a - *(int*)b;
}
int main(){
    int N, origin[100], halfsort[100], i, j, length;
    scanf("%d", &N);
    for(int i = 0; i < N; i++) scanf("%d", origin + i);
    for(int i = 0; i < N; i++) scanf("%d", halfsort + i);
    /* 如果是插入排序,则返回排序长度,如果是,则返回零 */
    for(i = 0; i < N - 1 && halfsort[i] <= halfsort[i + 1]; i++) ;
    for(length = ++i; i < N && halfsort[i] == origin[i]; i++) ;
    length = i == N ? length + 1 : 0;
    if(length){/* 插入排序 */
        puts("Insertion Sort");
        qsort(origin, length, sizeof(int), comp);
    }else{/* 归并排序,对原始数组进行操作 */
        put***erge Sort");
        for(length = 1, i = 0; i < N && length <= N; length *= 2){
            for(i = 0; i < N && origin[i] == halfsort[i]; i++) ;
            for(j = 0; j < N / length; j++)
                qsort(origin + j * length, length, sizeof(int), comp);
            qsort(origin + j * length, N % length, sizeof(int), comp);
        }
    }
    for(int i = 0; i < N; i++)
        printf("%d%c", origin[i], i == N - 1 ? '\n' : ' ');
    return 0;
}

发表于 2019-11-30 17:09:22 回复(0)
为啥PAT后面几个测试点过不去
#include <stdio.h>
#include <stdlib.h>
void sort(int a[],int l,int r)
{
    int i,j;
    for(i=l;i<=r;i++)
        for(j=l;j<r;j++)
        {
           if(a[j]>a[j+1])
           {
               int t=a[j];
               a[j]=a[j+1];
               a[j+1]=t;
           }
        }
}
int main()
{
    int n;
    int a1[110]={0};
    int a2[110]={0};
    int b[110];
    scanf("%d",&n);
    int i;
    for(i=0;i<n;i++)
    {
        scanf("%d",&a1[i]);
    }
    for(i=0;i<n;i++)
    {

        scanf("%d",&a2[i]);
    }
    for(i=0;i<n;i++)
    {
        if(a2[i]<a2[i+1])
            ;
        else
            break;
    }
    int j=i+1;
    int k=i+1;
    for(;j<n;j++)
    {
        if(a2[j]==a1[j])
            ;
        else
            break;
    }
    if(j==n)
    {
        printf("Insertion Sort\n");
        int t=a1[i+1];
        for(j=i;j>=0;j--)
        {
            if(a2[j]>t)
                a2[j+1]=a2[j];
            else
            {
                a2[j+1]=t;
                break;
            }
        }
        if(j==-1)
            a2[0]=t;
        for(j=0;j<n;j++)
        {

           printf("%d",a2[j]);
           if(j<n-1)
            printf(" ");
        }
    }
    else
    {

        printf("Merge Sort\n");
        while(k>=2)
        {

          for(i=k;i<2*k-1;i++)
          {
            if(a2[i]<a2[i+1])
                ;
            else
                break;
          }
          if(i!=2*k-1&&2*k-1<n)
          {
              k=k/2;
          }
          else
            break;
        }
        k=2*k;
        if(k>=n)
            sort(a2,0,n-1);
        else
        {

          i=0;
          while(i<n)
          {
            if(i+k-1<n)
            sort(a2,i,i+k-1);
            i=i+k;
          }
        }
        for(i=0;i<n;i++)
        {
            printf("%d",a2[i]);
            if(i!=n-1)
                printf(" ");
        }


    }
    return 0;
}
发表于 2019-07-04 23:14:10 回复(0)

迭代归并排序,自己使用步长1,2,4,8.....解决

# -*- coding : utf-8 -*-

def merge_sort(l,l2):
    i=2
    count=0
    while i<=len(l):
        result=[]
        for j in range(int(len(l)/i)):
            result+=merge(l[j*i:j*i+int(i/2)],l[j*i+int(i/2):j*i+i])
        result+=l[int(len(l)/i)*i:]
        l=result.copy()
        if result==l2:
            count=i*2
        if i==count:
            break
        i*=2
    return result
def merge(left, right):
    result = []
    while len(left) > 0 and len(right) > 0:
        if left[0] <= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    result += left
    result += right
    return result


_ = input()
l1 = list(map(int, input().split()))
l2 = list(map(int, input().split()))
# insert
insert = l1.copy()
merge_l = l1.copy()
insert_flag = False
count=0
for i in range(1, len(insert)):
    j = i - 1
    temp = insert[i]
    while j >= 0 and insert[j] > temp:
        insert[j + 1] = insert[j]
        j -= 1
    insert[j + 1] = temp
    if l2 == insert:
        insert_flag = True
        count=i+1
    if i==count:
        break

if insert_flag:
    print('Insertion Sort')
    print(' '.join([str(i) for i in insert]))
else:
    print('Merge Sort')
    merge = merge_sort(merge_l,l2)
    print(' '.join([str(i) for i in merge]))
发表于 2019-05-30 21:35:43 回复(0)
#pragma warning(disable:4996)
#include <iostream>
#include<algorithm>
#include<string>
#include<vector>
usingnamespacestd;
 
vector<int> merge_sort(vector<int> res, intiter) {
    intn = res.size(),i = iter;
    for(intj = 0; j < n; ) {
        if(pow(2, i) + j <= n) sort(res.begin() + j, res.begin() + j + pow(2, i));
        if(j + pow(2, i) > n) {
            sort(res.begin() + j, res.end()); break;
        }
        elsej += pow(2, i);
    }
    returnres;
}
 
vector<int> operator+(vector<int>& vec1, vector<int>& vec2) {
    intn = vec1.size() + vec2.size();
    vector<int> res(n, 0);
    for(inti = 0; i < n; i++) {
        if(i < vec1.size()) res[i] = vec1[i];
        elseres[i] = vec2[i - vec1.size()];
    }
    returnres;
}
 
voidinsertion_sort(vector<int>& res, inttarget) {
    vector<int> result;
    if(res.size() == 1) {
        if(target >= res[0]) { res.insert(res.begin()+1,1,target); }
        else{ res.insert(res.begin(),1,target); }
    }
    else{//size>=2
        boolflag = true;
        for(inti = 0; i < res.size(); i++) {
            if(res[i] >= target) {
                flag = false;
                res.insert(res.begin() + i, 1, target);
                break;
            }
        }
        if(flag) res.push_back(target);
    }
}
 
string vector_to_string(vector<int> res) {
    string str = "";
    for(auto&x : res) { str += to_string(x); }
    returnstr;
}
intmain()
{
    intn, iter = 0, i = 0, j = 0, t; scanf("%d\n", &n);
    vector<int> res(n, 0);string test = "";
    while(pow(2, iter) < n) { iter++;}
    while(i < n) { cin >> res[i]; i++; }
    vector<int> res1; res1.assign(res.begin(), res.end());
    while(j < n) { cin >> t; test += to_string(t); j++; }
    //cout << test << endl;
    for(inti = 1; i < iter; i++) { // 归并排序
        string result = "";
        res = merge_sort(res, i);
        result = vector_to_string(res);
        //for (auto&x : res) { result += to_string(x); }
        //cout << result << endl;
        if(test == result) {
            cout << "Merge Sort"<< endl;
            res = merge_sort(res, i + 1);
            for(auto&x : res) cout << x << " ";
            cin.get(); cin.get();
            return0;
        }
    }
    cout << "Insertion Sort"<< endl;
    vector<int> res2, temp;
    res2.push_back(res1[0]);
    for(inti = 1; i < n; i++) { // 选择排序,n-1轮迭代
        string result_choose = "";
        insertion_sort(res2, res1[i]); //前面有序部分
        if(res2[res2.size() - 1] <= res1[res2.size()]) { //前面有序时若待插入数,不影响子序列的有序性,直接插入该数,指针后移。
            res2.push_back(res1[res2.size()]);
            i++;
        }
        temp.assign(res1.begin() + i+1, res1.end()); //后面乱序部分
        res1 = res2 + temp; //排序后得结果
        result_choose = vector_to_string(res1);
        if(result_choose == test) {
            insertion_sort(res2, res1[i + 1]);
            temp.assign(res1.begin() + i + 2, res1.end()); //后面乱序部分
            res1 = res2 + temp; //排序后得结果
            for(auto&x : res1) cout << x << " ";
            cin.get(); cin.get();
            return0;
        }
        //cout << result_choose << endl;
    }
    cin.get(); cin.get(); return0;
}

编辑于 2019-04-25 20:59:31 回复(1)
#include "pch.h"
#include <iostream>
#include <algorithm>

using namespace std;

int main() {
    int N;
    int beforeSortArray[100];
    int sortingArray[100];
    int index = 0;
    bool isInsertSort = true;
    int mergeBatch;
    int batchAmount;
    cin >> N;
    for (int i = 0; i < N; i++) {
        cin >> beforeSortArray[i];
    }

    for (int i = 0; i < N; i++) {
        cin >> sortingArray[i];
    }

    for (int i = 0; i < N; i++) {
        if (sortingArray[i] > sortingArray[i + 1]) {
            index = i + 1;
            break;
        }
    }

    for (int i = index; i < N; i++) {
        if (beforeSortArray[i] != sortingArray[i]) {
            isInsertSort = false;
            break;
        }
    }

    if (isInsertSort) {
        cout << "Insertion Sort" << endl;
        int temp = sortingArray[index];
        int i = 0;
        for (i = index - 1; i >= 0 && temp < sortingArray[i]; i--) {
            sortingArray[i + 1] = sortingArray[i];
        }

        sortingArray[i + 1] = temp;
    }

    else {
        cout << "Merge Sort" << endl;
        mergeBatch = index * 2;
        batchAmount = N / mergeBatch;
        batchAmount = batchAmount + (N * 1.0 / mergeBatch - batchAmount != 0.0 ? 1 : 0);

        for (int i = 0; i < N; i += mergeBatch)
            sort(sortingArray + i, sortingArray + (i + mergeBatch >= N ? N: i + mergeBatch));
    }

    for (int i = 0; i < N; i++) {
        if (i < N - 1)
            cout << sortingArray[i] << " ";

        else {
            cout << sortingArray[i];
        }
    }

    return 0;
}
发表于 2019-03-15 21:23:49 回复(0)