码迷,mamicode.com
首页 > 编程语言 > 详细

案例7-1.2 插入排序还是归并排序 (25分)

时间:2020-03-14 17:00:54      阅读:199      评论:0      收藏:0      [点我收藏+]

标签:index   最大   eof   mem   turn   scan   amp   size   图片   

技术图片

 

 技术图片

 

 解题思路:

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;
}

 

案例7-1.2 插入排序还是归并排序 (25分)

标签:index   最大   eof   mem   turn   scan   amp   size   图片   

原文地址:https://www.cnblogs.com/snzhong/p/12492626.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!