/*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为要排序的元素个数。
归并排序的实现与分析