PAT-BASIC1035——插入与归并/PAT-ADVANCED1089/Data Structures and Algorithms7-13——Insert or Merge

我的PAT-BASIC代码仓:https://github.com/617076674/PAT-BASIC

我的PAT-ADVANCED代码仓:https://github.com/617076674/PAT-ADVANCED

我的Data Structures and Algorithms代码仓:https://github.com/617076674/Data-Structures-and-Algorithms

原题链接:

PAT-BASIC1035:https://pintia.cn/problem-sets/994805260223102976/problems/994805286714327040

PAT-ADVANCED1089:https://pintia.cn/problem-sets/994805342720868352/problems/994805377432928256

Data Structures and Algorithms7-13:https://pintia.cn/problem-sets/16/problems/675

题目描述:

PAT-BASIC1035:

PAT-ADVANCED1089、Data Structures and Algorithms7-13:

知识点:插入排序、归并排序

思路:根据插入排序和归并排序的定义求解

本题描述的归并排序是自底向上的归并算法。

插入排序和归并排序都不算难。本题的难点是要知道现在进行到了哪一步。

(1)首先判断是插入排序还是归并排序。正序遍历题目给的第二个数组,一旦发现nums[i] < nums[i - 1]的数据就记录i的值为index,并结束本次遍历。比较第一个数组和第二个数组中索引index及其之后的元素是否相同,如果相同,则说明是插入排序。否则,是归并排序。
(2)如果是插入排序,我们已经对第二个数组中的[0, index - 1]位置的索引进行了排序,继续插入排序第index位置。
(3)归并排序的下一个排列。归并排序归并的size是从1,2,4,8……这样递增的。关键在于怎么样确定归并排序的size。从size=2开始,判断每个子区间内是否有序,如果无序,则说明我们找出了当前需要排序的size值,跳出循环。以该size分隔子区间进行归并排序。

C++代码:

#include<iostream>
#include<algorithm>

using namespace std;

bool isInsertionSort(int* nums1, int* nums2, int N);
void nextInsertionSort(int* nums1, int* nums2, int N);
void nextMergeSort(int* nums1, int* nums2, int N);

int main() {
	int N;
	scanf("%d", &N);
	int nums1[N];
	int nums2[N];
	for(int i = 0; i < N; i++) {
		scanf("%d", &nums1[i]);
	}
	for(int i = 0; i < N; i++) {
		scanf("%d", &nums2[i]);
	}
	if(isInsertionSort(nums1, nums2, N)) {
		printf("Insertion Sort\n");
		nextInsertionSort(nums1, nums2, N);
	} else {
		printf("Merge Sort\n");
		nextMergeSort(nums1, nums2, N);
	}
	for(int i = 0; i < N; i++){
		printf("%d", nums2[i]);
		if(i != N - 1){
			printf(" ");
		}else{
			printf("\n");
		}
	}
	return 0;
}

bool isInsertionSort(int* nums1, int* nums2, int N) {
	int k = -1;
	for(int i = 0; i < N; i++) {
		if(*(nums2 + i + 1) < *(nums2 + i)) {
			k = i + 1;
			break;
		}
	}
	for(int i = k; i < N; i++) {
		if(*(nums1 + i) != *(nums2 + i)) {
			return false;
		}
	}
	return true;
}

void nextInsertionSort(int* nums1, int* nums2, int N) {
	int k = -1;
	for(int i = 0; i < N; i++) {
		if(*(nums2 + i + 1) < *(nums2 + i)) {
			k = i + 1;
			break;
		}
	}
	int temp = *(nums2 + k);
	int i = k;
	for(; *(nums2 + i - 1) > temp; i--){
		*(nums2 + i) = *(nums2 + i - 1);
	}
	*(nums2 + i) = temp;
}

void nextMergeSort(int* nums1, int* nums2, int N){
	int size = 2;
	bool flag = true;
	while(true){
		for(int i = 0; i < N; i += size){
			for(int j = i; j < i + size - 1 && j < N - 1; j++){	//j < N - 1别落了 
				if(*(nums2 + j + 1) < *(nums2 + j)){
					flag = false;
				}
			}
		}
		if(!flag){
			break;
		}
		size *= 2;
	}
	for(int i = 0; i < N; i += size){
		sort(nums2 + i, nums2 + min(i + size, N));
	}
}

C++解题报告:

JAVA代码:

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = Integer.parseInt(scanner.nextLine());
        String[] input1 = scanner.nextLine().split("\\s+");
        int[] array1 = new int[n];
        for (int i = 0; i < n; i++) {
            array1[i] = Integer.parseInt(input1[i]);
        }
        String[] input2 = scanner.nextLine().split("\\s+");
        int[] array2 = new int[n];
        for (int i = 0; i < n; i++) {
            array2[i] = Integer.parseInt(input2[i]);
        }
        if(isInsertionSort(array1, array2)){
            System.out.println("Insertion Sort");
            nextInsertionArray(array1, array2);
            for (int k = 0; k < n; k++) {
                System.out.print(array2[k]);
                if(k != n - 1){
                    System.out.print(" ");
                }
            }
        }else{
            System.out.println("Merge Sort");
            nextMergeArray(array1, array2);
            for (int k = 0; k < n; k++) {
                System.out.print(array2[k]);
                if(k != n - 1){
                    System.out.print(" ");
                }
            }
        }
    }

    private static boolean isInsertionSort(int[] array1, int[] array2){
        int i = array1.length - 1;
        for (; i >= 0; i--) {
            if(array1[i] != array2[i]){
                break;
            }
        }
        for (int j = 0; j < i; j++) {
            if(array2[j + 1] < array2[j]){
                return false;
            }
        }
        return true;
    }

    private static void nextInsertionArray(int[] array1, int[] array2){
        int i = 1;
        for (; i < array2.length; i++) {
            if(array2[i] < array2[i - 1]){
                break;
            }
        }
        int temp = array2[i];
        int j = i;
        for (; j - 1 >= 0 && array2[j - 1] >= temp; j--) {
            array2[j] = array2[j - 1];
        }
        array2[j] = temp;
    }

    private static void nextMergeArray(int[] array1, int[] array2){
        int size = 1;
        while(true) {
            boolean flag = true;
            size *= 2;
            for (int i = 0; i < array2.length; i += size) {
                for (int j = i; j < i + size - 1; j++) {
                    if(j + 1 < array2.length && array2[j + 1] < array2[j]){
                        flag = false;
                    }
                }
            }
            if(!flag){
                break;
            }
        }
        size /= 2;
        int[] tempArray = new int[array2.length];
        for (int i = 0; i < array2.length; i++) {
            tempArray[i] = array2[i];
        }
        for(int i = 0; i < array2.length; i += size * 2){
            int index1 = i;
            int index2 = i + size;
            int index = i;

            while(index1 < Math.min(i + size, array2.length) || index2 < Math.min(i + 2 * size, array2.length)){
                if(index1 >= i + size || index1 >= array2.length){
                    array2[index++] = tempArray[index2++];
                }else if(index2 >= i + 2 * size || index2 >= array2.length){
                    array2[index++] = tempArray[index1++];
                }else if(tempArray[index1] <= tempArray[index2]){
                    array2[index++] = tempArray[index1++];
                }else{
                    array2[index++] = tempArray[index2++];
                }
            }
        }
    }
}

JAVA解题报告:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值