排序算法的C语言实现(上 比较类排序:插入排序(5)

/*directls*/
int directls(const char *path,Directory **dir)
{
    DIR          *dirptr;
    Directory    *temp;
    struct dirent *curdir;
    int          count,i;
   
    /*打开目录*/
    if((dirptr = opendir(path)) == NULL )
            return -1;
    /*获取目录列表*/
    *dir = NULL;
    count =0;
   
    while((curdir = readdir(dirptr)) != NULL /*readdir()返回参数dir目录流的下个目录进入点*/ )
    {
        count ++;
        if((temp = (Directory*)realloc(*dir,count*sizeof(Directory))) == NULL)
        {
            free(*dir);
            return -1;
        }
        else
        {
            *dir = temp;
        }
       
        strcpy(((*dir)[count - 1]).name, curdir->d_name);
    }
    closedir(dirptr);
   
    /*将目录列表按名称排序*/
    if(qksort(*dir,count,sizeof(Directory),0,count-1,compare_dir) != 0)
        return -1;
   
    /*返回目录列表的数目*/
    return count;
}

三、归并排序

归并排序也是一种运用分治法排序的算法。与快速排序一样,它依赖于元素之间的比较来排序。但是归并排序需要额外的存储空间来完成排序过程。

我们还是以支票排序的例子说明。首先,将一堆未排序的支票对半分为两堆。接着,分别又将两堆支票对半分为两堆,以此类推,重复此过程,直到每一堆支票只包含一张支票。然后,开始将堆两两合并,这样每个合并出来的堆就是两个有序的合集,也是有序的。这个合并过程一直持续下去,直到一堆新的支票生成。此时这堆支票就是有序的。

由于归并排序也是一种分治算法,因此可以使用分治的思想把排序分为三个步骤

1、分:将数据集等分为两半;

2、治:分别在两个部分用递归的方式继续使用归并排序法;

3、合:将分开的两个部分合并成一个有序的数据集。

归并排序与其他排序最大的不同在于它的归并过程。这个过程就是将两个有序的数据集合并成一个有序的数据集。合并两个有序数据的过程是高效的,因为我们只需要遍历一次即可。根据以上事实,再加上该算法是按照可预期的方式来划分数据的,这使得归并排序在所有的情况下都能达到快速排序的平均性能

归并排序的缺点是它需要额外的存储空间来运行。因为合并过程不能在无序数据集本身中进行,所以必须要有两倍于无序数据集的空间来运行算法。这点不足极大的降低了归并排序在实际中的使用频率,因为通常可以使用不需要额外存储空间的快速排序来代替它

然而,归并排序对于处理海量数据处理还是非常有价值的,因为它能够按预期将数据集分开。这使得我们能够将数据集分割为更加可管理的数据,接着用归并排序法处理数据,然后不断的合并数据,在这个过程中并不需要一次存储所有的数据。

归并排序的接口定义

mgsort

int mgsort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1,const void key2));

返回值:如果排序成功,返回0;否则,返回-1。

描述:   利用归并排序将数组data中的元素进行排序。数据中的元素个数由size决定。每个元素的大小由esize决定。i和k定义当前排序的两个部分,其值分别初始化为0和size-1。函数指针compare指向一个用户定义的函数来比较元素的大小。其函数功能同issort中描述的一样。当mgsort返回时,data中包含已经排好序的元素。

复杂度:O(n lg n),n为要排序的元素个数。

归并排序的实现与分析

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4c44cb3108d7558c7fdff59fb643a7ba.html