PTA Data Structure Problem Set Week 9 -- Sorting (Part 1)

发表于 2020-08-27 00:53 1389 字 7 min read

cos avatar

cos

FE / ACG / 手工 / 深色模式强迫症 / INFP / 兴趣广泛养两只猫的老宅女 / remote

剑指offer day31 数学(困难)剑指offer day30 分治算法(困难)剑指offer day29 动态规划(困难)剑指offer day28 搜索与回溯算法(困难)剑指offer day27 栈与队列(困难)剑指offer day26 字符串(中等)剑指offer day25 模拟(中等)剑指offer day24 数学(中等)剑指offer day23 数学(简单)剑指offer day22 位运算(中等)剑指offer day21 位运算(简单)剑指offer day20 分治算法(中等)剑指offer day19 搜索与回溯算法(中等)剑指offer day18 搜索与回溯算法(中等)剑指offer day17 排序(中等)剑指offer day16 排序(简单)剑指offer day15 搜索与回溯算法(中等)剑指offer day14 搜索与回溯算法(中等)剑指offer day13 双指针(简单)剑指offer day12 双指针(简单)剑指offer day11 双指针(简单)剑指offer day10 动态规划(中等)剑指offer day9 动态规划(中等)剑指offer day8 动态规划(简单)剑指offer day7 搜索与回溯算法(简单)剑指offer day6 搜索与回溯算法(简单)剑指offer day5 查找算法(中等)剑指offer day4 查找算法(简单)剑指offer day3 字符串(简单)剑指offer day2 链表(简单)剑指offer day1 栈与队列(简单)冲刺春招-精选笔面试66题大通关day22冲刺春招-精选笔面试66题大通关day21冲刺春招-精选笔面试66题大通关day20冲刺春招-精选笔面试66题大通关day19冲刺春招-精选笔面试66题大通关18冲刺春招-精选笔面试66题大通关17冲刺春招-精选笔面试66题大通关16冲刺春招-精选笔面试66题大通关day15冲刺春招-精选笔面试66题大通关day14冲刺春招-精选笔面试66题大通关day13冲刺春招-精选笔面试66题大通关day12冲刺春招-精选笔面试66题大通关day11冲刺春招-精选笔面试66题大通关day10冲刺春招-精选笔面试66题大通关day9冲刺春招-精选笔面试66题大通关day8冲刺春招-精选笔面试66题大通关day7冲刺春招-精选笔面试66题大通关day6冲刺春招-精选笔面试66题大通关day5冲刺春招-精选笔面试66题大通关day4冲刺春招-精选笔面试66题大通关day3冲刺春招-精选笔面试66题大通关day2冲刺春招-精选笔面试66题大通关day12021 Fall PAT Grade B Real Exam Solutions and Post-Contest SummaryPAT Grade B Practice Reflections and Pitfall SummaryPTA Data Structures Problem Set Week 3 - Planting Trees (Binary Trees, etc.)PTA Data Structure Problem Set Week 11 -- Hash SearchPTA Data Structure Problem Set Week 10 -- Sorting (Part 2)PTA Data Structure Problem Set Week 9 -- Sorting (Part 1)PTA Data Structure Problem Set Week 8 -- Graphs (Part 3)PTA Data Structure Problem Set Week 7 -- Graphs (Part 2)PTA Data Structure Problem Set Week 6 -- Graphs (Part 1)PTA Data Structures Problem Set Week 5 - Heaps & Huffman Trees & Union-FindPTA Data Structures Problem Set Week 4 - Binary Search Trees & AVL TreesPTA Data Structures Problem Set Week 2 - Linear StructuresPTA Data Structures Problem Set Week 1 - Maximum Subsequence Sum Algorithm & Binary SearchMOOC ZJU Data Structures After-Class Problems Record - PTA Data Structures Problem Set (Complete)2020 Lanqiao Cup Provincial Mock Contest Problem Record
这篇文章整理了关于排序算法的几道练习题,主要涉及插入排序和归并排序的识别,以及与堆排序的区分。通过对比初始序列与多次迭代后的结果,判断使用的是插入排序、归并排序还是堆排序,并强调了循环实现归并排序的必要性。

This article has been machine-translated from Chinese. The translation may contain inaccuracies or awkward phrasing. If in doubt, please refer to the original Chinese version.

Problem Set Master Index Study reference blogs: Data Structure Study Notes <8> Sorting, Iterative Implementation of Merge Sort (for reference)

09-Sort 1 Sorting (25 pts)

Problem link

A platform for experimenting with various sorting algorithms. Have fun with it, then post your results in the forum — if you really can’t do it, you can look at the reference code provided. This is basic training, a must-do.

The results of various sorting algorithms tested in this problem are all written in the blog Data Structure Study Notes <8> Sorting. Here only the insertion sort code is provided.

Code

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn = 100005;
const int inf  = 0x3f3f3f;
int N;
ll a[maxn];
void Insertion_Sort(ll a[], int N) {
    for(int P = 1; P < N; P++) {
        ll t = a[P];//摸下一张牌
        int i;
        for(i = P; i > 0 && a[i-1] > t; --i)
            a[i] = a[i-1];  //移出空位 直到前面那个这个元素小于当前元素
        a[i] = t;   //新牌落位
    }
}
int main(){
    scanf("%d", &N);
    for(int i = 0; i < N; ++i)
        scanf("%lld", &a[i]);
    Insertion_Sort(a, N);
    for(int i = 0; i < N; ++i)
        printf(" %lld"+!i, a[i]);
    return 0;
}

Test Cases

在这里插入图片描述

09-Sort 2 Insert or Merge (25 pts)

Problem link

2014 PAT Winter Exam real problem, for students preparing for the exam to practice. Optional.

Problem Summary

Given the initial sequence of integers and a sequence that is the result of several iterations of some sorting method, can you tell which sorting method we are using? (Insertion sort or merge sort)

Approach

Store the initial sequence in two arrays, then perform insertion sort. After each iteration, check if the sequence matches. If it matches, perform one more iteration and output. If it never matches, then it’s merge sort. Got stuck on merge sort for a long time — the recursive version is hard to handle, so the iterative version should be used. For the iterative merge sort, see: Iterative Implementation of Merge Sort (for reference)

Code

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 110;
const int inf  = 0x3f3f3f;
int N;
ll a[maxn],A[maxn],Copya[maxn];
void swap(ll &a, ll &b){//交换a,b的值
    int tmp = a;
    a = b;
    b = tmp;
}
bool isSame(ll a[], int N) {
    for(int i = 0; i < N; ++i)
        if(a[i] != A[i]) return false;
    return true;
}
void Merge(ll a[],ll tmp[], int s, int m, int e) {
    //将数组a的局部a[s,m-1]和a[m,e]合并到数组tmp,并保证tmp有序
    int pb = s;
    int p1 = s, p2 = m;//p1指向前一半p2指向后一半
    while (p1 <= m-1 && p2 <= e) {
        if (a[p1] <= a[p2])
            tmp[pb++] = a[p1++];
        else
            tmp[pb++] = a[p2++];
    }
    while(p1 <= m-1)
        tmp[pb++] = a[p1++];
    while(p2 <= e)
        tmp[pb++] = a[p2++];
    for (int i = 0; i < e-s+1; ++i)
        a[s+i] = tmp[i];
}
void Merge_Pass(ll a[], ll b[], int N, int len) {
    //将a数组按len长度切分 归并到b
    //len为当前有序子列的长度
    int i;
    for(i = 0; i <= N - 2*len; i += 2*len)
        //找每一对要归并的子序列 直到倒数第二对
        Merge(a, b, i, i+len, i+2*len-1); //将a
    if(i+len < N) //最后有2个子列
        Merge(a, b, i, i+len, N-1);
    else  //最后只剩1个有序子列
        for(int j = i; j < N; ++j) b[j] = a[j];
}
void Merge_Sort(ll a[], int N) {
    bool flag = false;
    int len = 1;//初始化有序子列的长度
    ll tmp[maxn];
    while(len < N) {
        Merge_Pass(a, tmp, N, len);
        len *= 2;
        if(isSame(tmp, N)) flag = true;
        else if(flag) return;
        Merge_Pass(tmp, a, N, len);
        len *= 2;
        if(isSame(a, N)) flag = true;
        else if(flag) return;
    }
}
bool Insertion_Sort(ll a[], int N) {
    bool flag = false;
    for(int P = 1; P < N; P++) {
        ll t = a[P];//摸下一张牌
        int i;
        for(i = P; i > 0 && a[i-1] > t; --i)
            a[i] = a[i-1];  //移出空位 直到前面那个这个元素小于当前元素
        a[i] = t;   //新牌落位
        if(flag)
            return true;
        if(isSame(a, N)) {
            flag = true;
            continue;
        }
    }
    return false;
}
int main(){
    scanf("%d", &N);
    for(int i = 0; i < N; ++i) {
        scanf("%lld", &a[i]);
        Copya[i] = a[i];
    }
    for(int i = 0; i < N; ++i)
        scanf("%lld", &A[i]);
    if(Insertion_Sort(a, N)) {
        printf("Insertion Sort\n");
    } else {
        for(int i = 0; i < N; ++i)
            a[i] = Copya[i];
        Merge_Sort(a, N);
        printf("Merge Sort\n");
    }
    for(int i = 0; i < N; ++i) {
        printf(" %lld"+!i, a[i]);
    }
    return 0;
}

Test Cases

在这里插入图片描述

09-Sort 3 Insertion or Heap Sort (25 pts)

Problem link

2015 graduate school entrance exam real problem, for students preparing for the exam to practice. Optional.

Problem Summary

Similar to the previous problem, except merge sort is replaced with heap sort.

Code

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 110;
const int inf  = 0x3f3f3f;
int N;
ll a[maxn],A[maxn],Copya[maxn];
void swap(ll &a, ll &b){//交换a,b的值
    int tmp = a;
    a = b;
    b = tmp;
}
bool isSame(ll a[], int N) {
    for(int i = 0; i < N; ++i)
        if(a[i] != A[i]) return false;
    return true;
}
void PercDown(ll a[], int N, int rt) {
    //将N个元素的数组中以a[now]为根的子堆调整为最大堆
    int father, son;
    ll tmp = a[rt];
    for(father = rt; (father*2+1) < N; father = son) {
        son = father * 2 + 1;//左儿子
        if(son != N-1 && a[son] < a[son+1]) //右儿子存在且比左儿子大
            son++;
        if(tmp >= a[son]) break;//找到该放的地方
        else a[father] = a[son];//下滤
    }
    a[father] = tmp;
}
inline void BuildHeap(ll a[], int N) {
    for(int i = N/2-1; i >= 0; --i) {
        PercDown(a, N, i);
    }
}
void Heap_Sort(ll a[], int N) {
    bool flag = false;
    BuildHeap(a, N);
    for(int i = N-1; i > 0; --i) {
        swap(a[0], a[i]);//最大堆顶a[0]与a[i]交换
        PercDown(a, i, 0);//删除后进行调整
        if(flag) return;
        if(isSame(a,N)) flag = true;
    }
}
bool Insertion_Sort(ll a[], int N) {
    bool flag = false;
    for(int P = 1; P < N; P++) {
        ll t = a[P];//摸下一张牌
        int i;
        for(i = P; i > 0 && a[i-1] > t; --i)
            a[i] = a[i-1];  //移出空位 直到前面那个这个元素小于当前元素
        a[i] = t;   //新牌落位
        if(flag)
            return true;
        if(isSame(a, N)) {
            flag = true;
            continue;
        }
    }
    return false;
}
int main(){
    scanf("%d", &N);
    for(int i = 0; i < N; ++i) {
        scanf("%lld", &a[i]);
        Copya[i] = a[i];
    }
    for(int i = 0; i < N; ++i)
        scanf("%lld", &A[i]);
    if(Insertion_Sort(a, N)) {
        printf("Insertion Sort\n");
    } else {
        for(int i = 0; i < N; ++i)
            a[i] = Copya[i];
        Heap_Sort(a, N);
        printf("Heap Sort\n");
    }
    for(int i = 0; i < N; ++i) {
        printf(" %lld"+!i, a[i]);
    }
    return 0;
}

Test Cases

在这里插入图片描述

喜欢的话,留下你的评论吧~

© 2020 - 2026 cos @cosine
Powered by theme astro-koharu · Inspired by Shoka