我的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解题报告: