#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 110;
int origin[N], tempori[N], changed[N]; //原始数组、临时数组(原始数组备份)及目标数组
int n; //元素个数
bool isSame(int A[], int B[]) //判断数组A和数组B是否相同
{
for(int i = 1; i <= n; i++) //循环遍历
{
if(A[i] != B[i]) //如果有一个不相同,直接返回false
return false;
}
return true; //到这一步说明每个元素都相同,返回true
}
void showArray(int A[]) //输出数组
{
for(int i = 1; i <= n; i++)
{
printf("%d", A[i]);
if(i < n)
printf(" ");
}
printf("\n");
}
bool insertSort() //插入排序
{
bool flag = false; //记录是否存在数组tempori[]中间步骤与changed[]数组相同
for(int i = 2; i <= n; i++) //总共可能进行n - 1趟,实际不一定有
{
if(i != 2 && isSame(tempori, changed)) //中间临时数组与目标数组相同
flag = true; //并且不是初始序列
sort(tempori, tempori + i + 1); //插入部分直接用sort()函数代替
if(flag == true) //如果flag为true,则说明有中间数组匹配上目标数组,返回true
return true;
}
return false; //无法匹配上目标数组,返回false
}
void downAdjust(int low, int high) //对heap数组在[low, high]范围内进行调整
{ //其中low为 欲调整结点的 数组下标,high一般为 堆的 最后一个元素的 数组下标
int i = low, j= i * 2; //i为欲调整结点,j为其左孩子结点
while(j <= high) //存在孩子结点
{ //如果右孩子结点存在,且右孩子结点值大于左孩子结点值
if(j + 1 <= high && tempori[j + 1] > tempori[j])
{
j = j + 1; //让j存储右孩子结点下标
}
if(tempori[j] > tempori[i]) //如果孩子结点中最大的权值比父亲结点大
{
swap(tempori[j], tempori[i]); //交换最大权值的孩子结点与父亲结点
i = j; //令i为j
j = i * 2; //令j为i的左孩子结点,进入下一层
}
else{
break; //孩子结点的权值均比父亲结点的小,调整结束
}
}
}
void heapSort() //堆排序
{
bool flag = false;
for(int i = n / 2; i >= 1; i--)
{
downAdjust(i, n); //建堆,此时是从大到小的顺序
}
for(int i = n; i > 1; i--)
{
if( i != n && isSame(tempori, changed)) //中间临时数组序列与目标序列相同
flag = true; //并且不是初始序列
swap(tempori[i], tempori[1]); //交换heap[i]与堆顶
downAdjust(1, i - 1); ///调整堆顶
if(flag == true) //如果临时数组匹配上目标数组
{
showArray(tempori); //输出数组
return;
}
}
}
int main()
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%d", &origin[i]); //输入起始数组
tempori[i] = origin[i]; //tempori数组为备份,排序在tempori上进行
}
for(int i = 1; i <= n; i++)
{
scanf("%d", &changed[i]); //输入目标数组
}
if(insertSort()) //如果插入排序中找到目标数组
{
printf("Insertion Sort\n");
showArray(tempori);
}
else{ //到达此处时一定是堆排序
printf("Heap Sort\n");
for(int i = 1; i <= n; i++)
{
tempori[i] = origin[i]; //还原tempori数组
}
heapSort(); //堆排序
}
return 0;
}
【PAT A1098】Insertion or Heap Sort
最新推荐文章于 2024-11-02 09:55:19 发布