1098 Insertion or Heap Sort (25分)[插入排序][堆排序][×][屑题]

By Jalan

这题出的就是一坨狗屎,就是同样是堆排序,实现也是多样的,这里也没有明确的给出堆排每一步的限制,难道就让人自己摸索?
最恶心的是我用stl自带的heap去一步步排,居然构成的堆和结果的堆是细部不一致的,我想问问pta的人,你们的heap牛还是stl的heap牛啊?

知识工具需求

数学

数据结构和算法

  • 插入排序
  • 堆排序

语言

  • stl heap

题干

插入排序是每次迭代输入一个元素,找到他在目标排序中的位置,将他插入,直到没有输入为止
堆排序是把输入区分成排序好和没排序好的两个分段,每次迭代把未排序段最大的数字加入排序段.
给一个整型序列,给一个序列是某种排序的几次迭代结果,找出排序方式

输入条件

第一行N<=100是整型数量
N个整型,初始序列.
N个整型,现在序列
假设目标排序是升序

输出条件

第一行打印是"Insertion Sort" or “Heap Sort”
第二行打印再执行一次这种排序方法的迭代的排序
保证得到的方法唯一,末尾不能有空格

例子

例1

输入
10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0
输出
Insertion Sort
1 2 3 5 7 8 9 4 6 0

例2

输入
10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9
//
3 1 2 8 7 5 4 6 0 9
3 1 2 7 5 4 6 0 8 9
3 1 2 5 4 6 0 7 8 9  
输出
Heap Sort
5 4 3 1 0 2 6 7 8 9

题解

第一次

思路

  1. 输入这个数组
  2. 测试是哪种排序
  3. 针对排序写出一次迭代
  4. 输出迭代结果

预期时间复杂度

n

编写用时

没写出来

代码

代码来自https://blog.csdn.net/qq_45472866/article/details/106108806
我当时没写出来,参考了这个哥们的,写的比我好多了

CPP
#include<bits/stdc++.h> 
using namespace std;
const int N = 105;
 
int n, a[N], temp[N];
 
void downadj(int low, int high) {
    int i = low, j = i * 2;
    while (j <= high) {
        if (j + 1 <= high && temp[j + 1] > temp[j]) j++;
        if (temp[j] > temp[i]) {
            swap(temp[j], temp[i]);
            i = j;
            j = i * 2;
        }
        else  break;
    }
}
 
void insertsort(int i) {          //插排,将数组temp中的第i个元素插到它应该在的位置
    printf("Insertion Sort\n");
    if (i == n + 1) return;             //如果temp已经是a排好序的(这句可有可无,本题并没有这样的测试点)
    int t = temp[i], j;              //插排典型代码,不解释
    for (j = i - 1; j >= 1 && temp[j] > t; j--)
        temp[j + 1] = temp[j];
    temp[j + 1] = t;
}
 
void heapsort() {                  //堆排序
    printf("Heap Sort\n");
    int i = n;
    while (i && temp[i] > temp[1])
        i--;                     //从后往前找到第一个小于temp[1]的元素,那个元素即为根节点应该去的位置
    swap(temp[i--], temp[1]);
    downadj(1, i);           //向下调整法的堆排序
}
 
void read() {
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = 1; i <= n; i++)
        scanf("%d", &temp[i]);
}
 
int main() { 
    read();          //读入数据
    int i = 1, j;
    while (i < n && temp[i] <= temp[i + 1])  i++;      //从头开始遍历temp数组,找到不是升序的分界点。  注意这里的temp[i] <= temp[i + 1]的等号(测试点4的坑)
    for (j = i + 1; j <= n && a[j] == temp[j]; j++)      //从分界点开始遍历temp,判断temp和a是否完全吻合
        ;
    if (j == n + 1)  insertsort(i + 1);         //j == n + 1说明完全吻合,执行一次插排
    else   heapsort();                         //否则执行一次堆排
   
    for (int i = 1; i <= n; i++)          //输出处理过一次的temp数组
        printf("%d%s", temp[i], i < n ? " " : "\n");
    return 0;
}

自己写的,2点不过,但是没啥问题.

#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;

int main(int argc, char const *argv[])
{
    int N;
    scanf("%d", &N);
    vector<int> ori(N), test(N);
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &ori[i]);
    }
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &test[i]);
    }
    //插排特征是前部有序,堆排特征是后部一致.
    int isHeapSort = false;
    vector<int> ordered(test);
    sort(ordered.begin(), ordered.end());
    vector<int> h(test);
    make_heap(h.begin(), h.end());
    for (int i = N; i > 0; i--)
    {
        pop_heap(h.begin(), h.begin() + i);
        if (h == test)
        {
            isHeapSort = true;
            pop_heap(h.begin(), h.begin() + i - 1);
            break;
        }
    }
    if (isHeapSort)
    {
        printf("Heap Sort\n");
        for (int i = 0; i < N; i++)
        {
            printf("%d", h[i]);
            if (i != N - 1)
            {
                printf(" ");
            }
        }
    }
    else
    {
        int orderdIndex = 0;//指向最后一个排好的元素
        for (int i = 1; i < N; i++)
        {
            if (test[i-1] < test[i])
            {
                orderdIndex = i;
            }
            else
            {
                break;
            }
        }
        vector<int> I(test);
        int insertIndex=0;
        int insert=I[orderdIndex+1];
        for (int i = 0; i <=orderdIndex; i++)
        {
            if (insert<I[i])
            {
                insertIndex=i;
                break;
            }
        }
        //排序部分移动
        for (int i = orderdIndex+1;i>=insertIndex+1 ;i--)
        {
            I[i] = I[i - 1];
        }
        I[insertIndex]=insert;
        printf("Insertion Sort\n");
        for (int i = 0; i < N; i++)
        {
            printf("%d", I[i]);
            if (i != N - 1)
            {
                printf(" ");
            }
        }
    }

    return 0;
}
运行用时

结尾

看在我写了这么多注释的份上可以给我点个赞嘛,求求惹=]砰砰砰,给我加点写下去的油呀@.@
也欢迎关注我的CSDN账号呀,接下来两个月我应该会按这个格式更新所有的PTA甲级题目

                                        **开心code每一天**
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值