PAT 1098 Insertion or Heap Sort

题意:
给出数字n,接下来是一组数字序列,后面是这组数字经过一定次数排序后的序列,根据当前排序后的序列判断是插入排序还是堆排序。堆排序将序列分为两个部分,一个是未排序的大顶堆部分,另一个是排好序的部分,前半部分为大顶堆。判断完后,再输出下一个关键字排序后的结果。
解法:
判断:因为堆排序,前半部分是大顶堆,根据第一个元素是否大于第二个判断是堆排序。
插入排序主要找到第一个小于前一个元素的数,然后进行排序。
堆排序,将大顶堆的第一个元素和最后一个元素交换,找到第一个大小比第一个元素的大的数,它的前一个位置就是大顶堆的最后一个元素。再进行大顶堆的调整。
总结:
主要难点在大顶堆的调整:
数组下标从0开始,左节点为2当前节点下标+1,右节点为2当前节点下标+2。.
数组下标从1开始,左节点为2当前节点下标,右节点为2当前节点下标+1。
(用时:1:21:46.32)

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<cstring>
#include<cmath>
//#include<bits/stdc++.h>
using namespace std;

int main()
{
    int n;
    scanf("%d",&n);
    int initial[n];
    for(int i=0; i<n; i++) {
        scanf("%d",&initial[i]);
    }
    int sortArray[n];
    for(int i=0; i<n; i++) {
        scanf("%d",&sortArray[i]);
    }
    int issame = true;
    for(int i=0; i<n; i++) {
        if(sortArray[i]!=initial[i]) {
            issame =false;
            break;
        }
    }
    int index = -1;
    if(issame||sortArray[0]<=sortArray[1]) {
        printf("Insertion Sort\n");
        for(int i=1; i<n; i++) {
            if(sortArray[i-1]>sortArray[i]) {
                index = i;
                break;
            }
        }

        if(index>0) {
            int val = sortArray[index];
            int j=0;
            for(j=index-1; j>=0&&sortArray[j]>val; j--) {
                sortArray[j+1] = sortArray[j];
            }
            sortArray[j+1] = val;
        }
    } else {
        printf("Heap Sort\n");
        for(int i=1; i<n; i++) {
            if(sortArray[0]<sortArray[i]) {
                index = i;
                break;
            }
        }

        if(index>1) {
            int t= sortArray[0];
            sortArray[0] = sortArray[index-1];
            sortArray[index-1] = t;
            index--;
            int sIndex = 0;

            while(sIndex<index) {
                int lIndex = sIndex * 2+1;
                int rIndex = lIndex + 1;
                if(lIndex>=index) {
                    break;
                }

                if(rIndex<index) {
                    int maxIndex = sortArray[lIndex] >= sortArray[rIndex]? lIndex:rIndex;
                    if(sortArray[sIndex]<sortArray[maxIndex] ) {
                        t=sortArray[maxIndex];
                        sortArray[maxIndex] = sortArray[sIndex];
                        sortArray[sIndex] = t;
                        sIndex = maxIndex;
                    } else {
                        break;
                    }
                } else {
                    if(sortArray[sIndex]<sortArray[lIndex] ) {
                        t=sortArray[lIndex];
                        sortArray[lIndex] = sortArray[sIndex];
                        sortArray[sIndex] = t;
                        sIndex = lIndex;
                    } else {
                        break;
                    }

                }
            }
        }
    }

    for(int i=0; i<n; i++) {
        if(i==0) {
            printf("%d",sortArray[i]);
        } else {
            printf(" %d",sortArray[i]);
        }
    }
    printf("\n");

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值