openjudge:置换选择排序

回眸只為那壹抹淺笑 提交于 2020-02-05 05:11:13

1:置换选择排序
查看提交统计提问
总时间限制: 1000ms 内存限制: 65536kB
描述
给定初始整数顺串,以及大小固定并且初始元素已知的二叉最小堆(为完全二叉树或类似完全二叉树,且父元素键值总小于等于任何一个子结点的键值),要求利用堆实现置换选择排序,并输出第一个顺串。例如给定初始顺串29,14,35,13,以及堆(记为16 19 31 25 21 56 40), 置换选择排序得到的第一个顺串为16 19 21 25。

输入
第一行包含两个整数,m为初始顺串的数的个数,n为二叉最小堆的大小
第二行包含m个整数,即初始顺串
第三行包含n个整数,即已经建好的堆的元素(有序,按照从堆顶到堆底,从左到右的顺序)
输出
输出包含一行,即第一个顺串。
样例输入
4 7
29 14 35 13
16 19 31 25 21 56 40
样例输出
16 19 21 25

#include <iostream>
#include <cstdio>
using namespace std;
int myheap[100000];
int tmp[100000];
int m, n;
int last;
void shiftdown(int k)
{
    int f = k;
    int s = f * 2 + 1;
    int t = myheap[f];
    while(s < last)
    {
        if(s < last - 1 && myheap[s] > myheap[s + 1])
        {
            s++;
        }
        if(t > myheap[s])
        {
            myheap[f] = myheap[s];
            f = s;
            s = f * 2 + 1;
        }
        else
        {
            break;
        }
    }
    myheap[f] = t;
}

int main()
{
    cin >> m >> n;
    last = n;
    for (int i = 0; i < m;i++)
    {
        scanf("%d", tmp + i);
    }
    for (int i = 0; i < n;i++)
    {
        scanf("%d", myheap + i);
    }
    int ago = -10000000;
    for (int i = 0; i < m;i++)
    {
        if(last <= 0) // 求第一个顺串,注意这个,m不一定小于n!!
            break;
        printf("%d ", myheap[0]);
        ago = myheap[0];
        if(tmp[i] >= ago)
        {
            myheap[0] = tmp[i];
        }
        else 
        {
            myheap[0] = myheap[last - 1];
            myheap[last - 1] = tmp[i];
            last--;
        }
        shiftdown(0);
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!