PAT乙 1035 插入与归并 (GO)

该博客主要探讨PAT乙1035题目,解析了如何判断输入的数组是由插入排序还是归并排序得到的。作者首先介绍了两种排序方法的特点,并提供了错误思路,指出不应直接实现排序算法。接着,博主提出通过检查数组顺序和剩余部分来区分排序类型,对于插入排序,只需将下一位元素插入排序;对于归并排序,博主采用模拟归并排序过程的方法,直到匹配目标数组,再进行一次排序。测试点展示了不同类型的排序情况。
摘要由CSDN通过智能技术生成

思路:
本题浪费了一点时间,和大家一样都以为是考察插入排序和归并排序,我就先把插入和归并排序都写好了。后来发现并不没有那么简单。

  1. 理解插入排序和归并排序的特征
  2. 插入排序是依次从数组中取一位,插入到前面的数组。插入排序
  3. 在了解插入排序的基础上,我们可以循环已经排过序的数组,数组是否从小到大排序,直到a[i] > a[i+1],并且数组剩下的部分和原始数组一致,则可以判定为是插入排序,反之为归并排序
  4. 确定是哪种排序之后,如果是插入排序,那么把下一位丢进去进行一次排序即可,难的是归并排序
  5. 没有想到好的办法,把原始数组按照归并排序,依次模拟,中间排序用sort函数,直到和目标数组一致,然后再执行一次排序。归并的可能比较难理解
  6. 测试点:插入排序(测试点0、2、4) 归并排序(测试点1、3、5、6)
package main

import (
	"fmt"
	"sort"
)

func  main() {
	var n int
	var a, b [100]int
	_, _ = fmt.Scanf("%d", &n)
	for i:=0; i<n; i++ {
		_, _ = fmt.Scanf("%d", &a[i])
	}
	for i:=0; i<n; i++ {
		_, _ = fmt.Scanf("%d", &b[i])
	}

	j := 0
	i := 0
	for i=1; i<n; i++ {
		if b[i - 1] > b[i] {
			j = i
			break
		}
	}
	for i=j; i<n; i++ {
		if a[i] != b[i] {
			break
		}
	}

	if i == n {
		fmt.Println("Insertion Sort")
		result := nextInsertionSort(b[:n], j)
		for k:=0; k<n-1; k++ {
			fmt.Printf("%d ", result[k])
		}
		fmt.Printf("%d\n", result[n-1])
	} else {
		fmt.Println("Merge Sort")
		result := nextMergeSort(a[:n], b[:n])
		for k:=0; k<n-1; k++ {
			fmt.Printf("%d ", result[k])
		}
		fmt.Printf("%d\n", result[n-1])
	}
}

func nextInsertionSort(arr []int, step int) []int  {
	temp := arr[step]
	j := step - 1
	for j >= 0 && arr[j] > temp {
		arr[j+1] = arr[j]
		j--
	}
	arr[j+1] = temp
	return arr
}

func nextMergeSort(r1, r2 []int) []int {
	length := len(r1)
	flag := false
	num := 1
	for !flag {
		flag = myEq(r1, r2)
		num *= 2
		i := 0
		for i=0; i<length/num; i++{
			start := i * num
			end := (i + 1) * num
			sort.Ints(r1[start:end])
		}
		sort.Ints(r1[i * num:length])

	}
	return r1
}

func myEq(a, b []int) bool {
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值