案例7-1.2 插入排序還是歸並排序 (25分)


 

 

 

 解題思路:

1、區分是插入還是歸並

     1)插入:前段有序,后段與初始序列一致。找到第一個破壞序列有序的下標,再繼續下一輪插入排序

 

  2)歸並:段內有序,需確定最后歸並長度。從歸並段為2,4,8...開始找起,看是否每段段內有序,如果其中某段不滿足有序,則記下當前歸並段長度,再將歸並段*2即為下次歸並長度。

 

 

#include <stdio.h>
#include <string.h>
int Judge(int a[],int b[],int n) {//判斷是插入還是歸並段
    int i,flag=0,pos=0;
    for(i=1; i<n; i++) {
        if(b[i-1]<=b[i]) {
            flag=1;
        } else {
            pos=i;
            break;
        }
    }
    if(flag) {
        for(i=pos; i<n; i++) {
            if(a[i]!=b[i]) {
                pos=0;
                break;
            }
        }
    } else
        pos=0;
    return pos;
}
void NextInsertionSort(int a[],int pos,int n) {//下一次插入排序
    int i,tmp=a[pos];
    int index;
    for(i=0; i<pos; i++) {
        if(a[i]>tmp) {
            index=i;
            break;
        }
    }
    for(i=pos-1; i>=index; i--) {
        a[i+1]=a[i];
    }
    a[index]=tmp;
}
int k=0;
void Merge(int a[],int low,int high,int mid) {//兩段歸並成一段
    int i,j;
    int c[100]= {0};
    for(i=low; i<=high; i++) {
        c[i]=a[i];
    }
    i=low,j=mid+1;
    while(i<=mid&&j<=high) {
        if(c[i]<=c[j]) {
            a[k++]=c[i];
            i++;
        } else {
            a[k++]=c[j];
            j++;
        }
    }
    while(i<=mid) {
        a[k++]=c[i];
        i++;
    }
    while(j<=high) {
        a[k++]=c[j];
        j++;
    }


}
int GetMergeLen(int a[],int n) {//獲得當前歸並段的最大長度
    int i,j;
    for(j=2; j<=n; j*=2) {//j<=n
        for(i=j; i<n; i=i+2*j)//i<n
        {
            if(a[i-1]>a[i])
                break;
        }    
        if(i<n)
            break;
    }
    return j;
}
void NextMergeSort(int a[],int low,int high,int len) {//下一次歸並
    int i;
    for(i=low; i<=high; i+=len) {
        int mid=(i+i+len-1)/2;
        if(i+len-1<=high) {
            Merge(a,i,i+len-1,mid);
        }
        else if(mid<high) {
            Merge(a,i,high,mid);
        }
    }

}
int main() {
    int n;
    scanf("%d",&n);
    int i;
    int a[n],b[n];
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    for(i=0; i<n; i++) {
        scanf("%d",&a[i]);
    }
    for(i=0; i<n; i++) {
        scanf("%d",&b[i]);
    }
    int pos=Judge(a,b,n);
    if(pos) {
        printf("Insertion Sort\n");
        NextInsertionSort(b,pos,n);
    } else {
        printf("Merge Sort\n");
        int len=2*GetMergeLen(b,n);//下一次歸並段長度=當前歸並段長度*2
        NextMergeSort(b,0,n-1,len);
    }
    for(i=0; i<n; i++) {
        if(i)
            printf(" ");
        printf("%d",b[i]);
    }
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM