• 算法之路——归并排序


      归并排序是令一类排序方法。即:将多个有序的表合成一个新的有序的表。这里主要是2—路归并排序。

      可以用递归和非递归的方法实现。

    实现代码如下:

    /*这是merge_sort.h文件*/
    #ifndef merge_sort
    #define merge_sort

    #define MAXSIZE 100
    typedef int KeyType;

    typedef struct {
    KeyType data;
    //其他的属性
    }RedType,* PRedType;

    typedef struct {
    RedType list[MAXSIZE];
    int length;
    }SqList, * PSqList;

    #define K_T "%d" //用于输入输出 如 printf(K_T, p->list[i].data);

    #define OK 0
    #define P_NULL 1
    #define TOOBIG 2
    #define NUM_ERROR 3

    int inputList (PSqList p,int length);
    int outputList (PSqList p);
    int mergeSort (PSqList p, PSqList d, int (*comp)(void *, void *));
    #endif

    /*这是merge_sort.cpp文件*/
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include "merge_sort.h"

    int inputList (PSqList p,int length)
    {//输入序列

    if (p == NULL)
    return P_NULL; //1,指针是空的
    if (length > MAXSIZE)
    return TOOBIG; //2,要输入的序列太多
    srand(time(NULL));
    int i = 0;
    for (i = 0; i < length; i++)
    p->list[i].data = rand()%10000;
    //if (scanf(K_T,&(p->list[i].data)) != 1)
    // return NUM_ERROR; //3,输入的数字有误
    p->length = length;
    return OK; //0
    }

    int outputList (PSqList p)
    {//输出序列
    if (p == NULL)
    return P_NULL;

    int i = 0;
    for (i =0; i < p->length; i++)
    printf (K_T"\t",p->list[i].data);
    putchar('\n');
    return OK;
    }//outputList

    static int merge (PSqList p, PSqList d,int (*comp)(void *,void *), int s, int m, int n)
    {
    //本来是没使用tmp作为中转的,后来考虑到,如果p和d是一个列表就会出现问题。而且下面给的非递归版的归并排序,p和d是同以个列表
    PSqList tmp; //如果用全局变量就不用每次申请了
    tmp = (PSqList)malloc(sizeof(SqList));
    tmp->length = p->length;
    int i = s;
    int j = m + 1;
    int k = s;

    while (i <= m && j <= n)
    {
    if (comp(&(p->list[i]), &(p->list[j])) < 0)
    tmp->list[k++] = p->list[i++];
    else
    tmp->list[k++] = p->list[j++];
    }

    while (i <= m)
    tmp->list[k++] = p->list[i++];

    while (j <= n)
    tmp->list[k++] = p->list[j++];

    for (i = s; i <= n; i++)
    d->list[i] = tmp->list[i];
    free(tmp);
    return 0;
    }

    static int mSort (PSqList p, PSqList d, int (*comp)(void *, void *), int s, int n)
    {
    if (s == n)
    {
    d->list[s] = p->list[s];
    return 0;
    }
    SqList t;
    t.length = p->length;

    int m;
    m = (s + n)/2;

    mSort(p, &t, comp, s, m);
    mSort(p, &t, comp, m + 1, n);
    merge(&t, d, comp, s, m, n);
    return OK;
    }//mSort


    int mergeSort (PSqList p, PSqList d, int (*comp)(void *, void *))
    {
    mSort (p, d, comp, 0, p->length-1);
    return OK;
    }

    /*
    int mergeSort (PSqList p, PSqList d,int (*comp)(void *, void *))
    {//这是非递归实现的归并排序,第二个参数是不需要的,这里只是为了和之前的函数兼容
    //将p归并排序,需要改变原本的p列表的内容,排序后的结果还是保留在p中。如果要不改变p并且将排序后的结果放在d中则只需开辟一个中转站即可
    d = p;
    int i,j;
    for (i = 1; i < p->length; i*=2)
    {
    for (j = 0; j+2*i-1 < p->length; j = j+2*i)
    {
    merge (p, d, comp, j, j+i-1, j+2*i-1);
    }
    if (j+i-1 <p->length-1)
    merge (p, d, comp, j, j+i-1, p->length-1);
    }
    return OK;
    }
    */

    /*这是main.cpp文件*/
    #include <stdio.h>
    #include <stdlib.h>
    #include "merge_sort.h"
    int comp(void *, void *);
    int main (int argc, char * argv)
    {
    int status;
    PSqList test;
    test = (PSqList)malloc(sizeof(SqList));
    PSqList dist;
    dist = (PSqList)malloc(sizeof(SqList));
    int n = 0 ;
    printf("请输入第一组待排序的数的个数(输入0结束循环):");

    while (1)
    {
    while (scanf("%d",&n) != 1)
    {
    puts("输入有误!请重新输入!");
    while(getchar() != '\n');
    }

    if (n == 0) //结束
    break;
    if (status = inputList(test, n) != 0)
    {
    puts("输入的数字有误!");
    while(getchar() != '\n');
    //exit(status);
    }

    dist->length = n;
    mergeSort(test, dist, comp);
    outputList (dist);
    printf("请输入下一组待排序的数的个数(输入0结束循环):");
    }
    free(test);
    free(dist);
    return 0;
    }

    int comp(void * d1, void * d2)
    {//比较函数
    return (((PRedType)d1)->data - ((PRedType)d2)->data );
    }



  • 相关阅读:
    (项目)在线教育平台(四)
    (项目)在线教育平台(三)
    (项目)在线教育平台(二)
    (项目)在线教育平台(一)
    (面试题)python面试题集锦-附答案
    (python)面向对象
    (python)数据结构---元组
    myEclipse 配置tomcat清除缓存
    Jquery浅克隆与深克隆
    列表上下无缝滚动
  • 原文地址:https://www.cnblogs.com/svking/p/merge_sort.html
Copyright © 2020-2023  润新知