Insert or Merge

  • Title Description

  • Topic ideas

1 The first step is how to distinguish between insertion sort and merge sort, insertion sort front part is ordered, the processing sequence has not a part of the back does not change.

2 Continue iteration

Continue iteration (1) insertion sort is better realized, just start from the first element of disorder can be part of the execution cycle.

(2) the difficulty lies in finding merge merge sort segment, after finding the right merge segment, the non-recursive merge sort of trip to perform.
Merge segment length determination code is as follows:

//计算归并段的长度并返回归并段长度
int MergeLength(int *B,int N)
{
    int l = 0;
    int i = 0;
    for (l = 2;l <= N;l = l * 2)
    {
        for (i = l;i < N;i = i + l * 2)
        {
            if (B[i] < B[i-1])
            {
                break;
            }
        }
        if (i < N)
        {
            break;
        }
    }
    return l;
}

  • C language
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>

int IsInsertion(int *A,int *B,int N)
{
    int i, k;
    for (i = 1;i < N;i++)
    {
        if (B[i] < B[i-1])
        {
            break;  //发现顺序不对 跳出循环
        }
    }
    k = i;  //保存跳出点 为下一次进行插入排序做准备
    for (;i < N;i++)
    {
        if (A[i] != B[i])
        {
            break;  //后面的序列有变化 说明不是插入排序 而是归并排序
        }
    }
    if (i == N)
    {
        return k;  //是插入排序 返回插入的位置
    }
    else
    {
        return 0;  //不是插入排序
    }
}

void PrintResults(int *B,int N)
{
    for (int i = 0;i < N - 1;i++)
    {
        printf("%d ",B[i]);
    }
    printf("%d", B[N-1]);
}

void NextInsertion(int *B,int N,int K)
{
    int tmp;
    int i = 0;
    printf("Insertion Sort\n");
    
    tmp = B[K];

    for (i = K-1;i >= 0;i--)
    {
        if (tmp < B[i])
        {
            B[i + 1] = B[i];
        }
        else
        {
            break;
        }
    }
    B[i + 1] = tmp;
    PrintResults(B,N);
}
//计算归并段的长度并返回归并段长度
int MergeLength(int *B,int N)
{
    int l = 0;
    int i = 0;
    for (l = 2;l <= N;l = l * 2)
    {
        for (i = l;i < N;i = i + l * 2)
        {
            if (B[i] < B[i-1])
            {
                break;
            }
        }
        if (i < N)
        {
            break;
        }
    }
    return l;
}

void NextMerge(int *B,int N)
{
    int p1, p2;
    int i;
    int p;
    int L;  //当前归并段的长度
    int *Tmp;
    printf("Merge Sort\n");
    L = MergeLength(B,N);

    Tmp = (int *)malloc(sizeof(int) * N);
    p = 0;  //p指向Tmp中当前处理的位置
    
    for (i = 0;i < (N-L-L);i = i + L + L)  //两两归并长度为L的段
    {
        p1 = i;
        p2 = i + L;  //p1和p2分别指向两个段的当前处理位置
        while ((p1 < (i + L)) && (p2 < (i + L + L)))
        {
            if (B[p1] > B[p2])
            {
                Tmp[p++] = B[p2++];
            }
            else
            {
                Tmp[p++] = B[p1++];
            }
        }  //end while ((p1 < (i + L)) && (p2 < (i + L + L)))
        while (p1 < (i + L))
        {
            Tmp[p++] = B[p1++];
        }
        while (p2 < (i + L + L))
        {
            Tmp[p++] = B[p2++];
        }
    }
    
    if ((N-i) > L)
    {
        p1 = i;
        p2 = i + L;
        while ((p1 < (i+L)) && (p2 < N))
        {
            if (B[p1] > B[p2])
            {
                Tmp[p++] = B[p2++];
            }
            else
            {
                Tmp[p++] = B[p1++];
            }
        }
        while (p1 < (i + L))
        {
            Tmp[p++] = B[p1++];
        }
        while (p2 < (i + L + L))
        {
            Tmp[p++] = B[p2++];
        }
    }
    else
    {
        while (i < N)
        {
            Tmp[i] = B[i++];
        }
    }

    PrintResults(Tmp,N);
}

int main()
{
    int *A;
    int *B;
    int N;
    int k;
    scanf("%d",&N);
    A = (int *)malloc(sizeof(int) * N);
    B = (int *)malloc(sizeof(int) * N);
    
    for (int i = 0;i < N;i++)
    {
        scanf("%d",&A[i]);
    }

    for (int i = 0; i < N; i++)
    {
        scanf("%d", &B[i]);
    }

    if (k = IsInsertion(A,B,N))
    {
        NextInsertion(B,N,k);
    }
    else
    {
        NextMerge(B,N);
    }
    // system("pause");
    return 0;
}

Guess you like

Origin www.cnblogs.com/Manual-Linux/p/11444837.html