PAT A1098 Insertion or Heap Sort

南笙酒味 提交于 2020-01-23 07:04:38
#include <stdio.h>
#include <stdlib.h>

//为了方便起见,数组下标从1开始
int stepi(int a[],int n)//n为数组长度
{
    int count=0;
    int x=a[1];
    for(int i=2;i<=n;i++)
    {
        if(a[i]>=x){
            count++;
            x=a[i];
        }
        else break;//需要使用break跳出
    }
    return count;
}//返回序列中已经有序的前count+1个数字的长度count+1

int flag;//用于判断为何种类型的sort 初始化为0

void swap(int *a,int *b)
{
    int temp=*a;
    *a=*b;
    *b=temp;
}

int isinsert(int a[],int b[],int n)
{
    for(int i=1;i<=n;i++)
    {
        if(a[i]!=b[i])return 0;//从
    }
    return 1;
}


void Insertsort(int a[],int n,int count,int b[])
{/*对长度为n的数组a进行count次排序,排序后和数组b进行比对,
    如果相等就输出Insert sort 和下一次排序的序列,
    否则就flag=0不改变,表示为推排序,进行堆排序推导*/
    for(int i=1;i<=count;i++)//进行count次排序
    {
        for(int j=i+1;j>=2;j--)
        {
            if(a[j]>=a[j-1])break;
            else
            {
                swap(&a[j],&a[j-1]);
            }
        }
        if(isinsert(a,b,n)){//只要有一次相同就是插入排序
            flag=1;
            break;//加不加break都可以,前count+1个元素已经有序,再进行插排,数组排列不改变
        }
    }
    if(flag==0)return;//为堆排序
    for(int j=count+2;j>=2;j--)//再进行一次变换
    {
        if(a[j]>=a[j-1])break;
        else
        {
            swap(&a[j],&a[j-1]);
        }
    }
    printf("Insertion Sort\n");
    for(int i=1;i<=n;i++)
    {
        printf("%d",a[i]);
        if(i<n)printf(" ");
    }

}

void Adjustdown(int a[],int k,int len)//k为要下调的元素的数组下标
{
    int i;
    a[0]=a[k];
    for(i=k*2;i<=len;i*=2)
    {
        if(i<len&&a[i+1]>a[i])i++;
        if(a[0]>=a[i])break;
        else
        {
            a[k]=a[i];
            k=i;//之后i*=2,相当于i又是k的孩子
        }
    }
    a[k]=a[0];
}

void buildmaxheap(int a[],int len)
{
    for(int i=len/2;i>=1;i--)
    {
        Adjustdown(a,i,len);
    }
}

void heapsortAndcompare(int a[],int len,int b[])
{
    buildmaxheap(a,len);
    for(int i=len;i>1;i--)//len-1趟交换 i>1不能=1
    {
        swap(&a[i],&a[1]);
        Adjustdown(a,1,i-1);//第三个参数为i-1而不是len-1
        if(a[i]!=b[i])break;//
    }
    printf("Heap Sort\n");
    for(int j=1;j<=len;j++)
    {
        printf("%d",a[j]);
        if(j<len)printf(" ");
    }
}



int main()
{
    //freopen("input.txt","r",stdin);
    //插入排序传入a数组要使用temp数组,在函数过程中会改变原来a数组
    int n,i,count;
    flag=0;
    scanf("%d",&n);
    int a[n+1],b[n+1],temp[n+1];
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        temp[i]=a[i];//temp为a的复制数组
    }
    for(i=1;i<=n;i++)
    {
        scanf("%d",&b[i]);
    }//输入a b数组
    count=stepi(b,n);
    Insertsort(temp,n,count,b);
    if(flag==1)return 0;//flag==1表示为插入排序
    //下面开始Heapsort
    heapsortAndcompare(a,n,b);
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!