类型无关的C语言通用冒泡排序函数

10 篇文章 0 订阅
1 篇文章 0 订阅

最近教小家伙C语言,很快就要教到排序了,所以写了个通用的冒泡排序程序。这个函数可以对任意类型数组中的数据排序。

需要用到的数据类型和函数声明如下(sort.h):

#ifndef __SORT_H
#define __SORT_H

#include <stdlib.h>

#ifndef __cplusplus
typedef enum
{
   false,
   true,
} bool;
#endif // __cplusplus

typedef enum
{
   SD_ASCEND,
   SD_DESCEND
} SortDirection;
typedef unsigned char byte;

/**
 * Comparator - function pointer to user defined comparator function.
 * @param one - data one, the first data to be compared.
 * @param two - data two, the second data to be compared.
 * @return - if one gt two, return positive integer; else if one lt two, return negative integer; else, return 0.
 */
typedef int (*Comparator)(void *one, void *two, size_t elemSize);

void swap(void *one, void *two, size_t size);

/**
 * sortBubbly - generic bubble sort function
 * @param unsorted - void pointer, point to an unsorted array.
 * @param sorted - void pointer, point to the sorted array.
 * @param cmpr - a comparator function. see the definition of Comparator.
 * @param dir - sort by ascend or descend.
 * @param elemCount - how many elements in the sorting array.
 * @param elemSize - the memory size of the single element in the array.
 */
void sortBubbly(void *unsorted, void *sorted, Comparator cmpr, SortDirection dir, int elemCount, size_t elemSize);

#endif /* __SORT_H_ */

函数实现代码如下(sort.c):

#include <string.h>
#include <stdlib.h>
#include "sort.h"

void swap(void *one, void *two, size_t size)
{
   void *relay = malloc(size);
   memcpy(relay, one, size);
   memcpy(one, two, size);
   memcpy(two, relay, size);
   free(relay);
}

void sortBubbly(void *unsorted, void *sorted, Comparator cmpr, SortDirection dir, int elemCount, size_t elemSize)
{
   void *onePtr, *twoPtr;
   bool willSwap;
   memcpy(sorted, unsorted, elemSize * elemCount);
   for(int index = 0; index < (elemCount - 1); index ++)
   {
      for(int swapIndex = 0; swapIndex < (elemCount - 1 - index); swapIndex ++)
      {
         onePtr = sorted + swapIndex * elemSize;
         twoPtr = sorted + (swapIndex + 1) * elemSize;
         if (dir == SD_DESCEND)
         {
            willSwap = (cmpr(onePtr, twoPtr, elemSize) < 0) ? true : false;
         }
         else
         {
            willSwap = (cmpr(onePtr, twoPtr, elemSize) > 0) ? true : false;
         }

         if (willSwap)
         {
            swap(onePtr, twoPtr, elemSize);
         }
      }
   }
}

测试验证代码如下:

#include <stdio.h>
#include <string.h>
#include "sort.h"

int integerComparator(void *one, void *two, size_t elemSize)
{
   return (*(int *)one) - (*(int *)two);
}

int floatComparator(void *one, void *two, size_t elemSize)
{
   float sub = (*(float *)one) - (*(float *)two);
   return ((sub > 0) ? 1 : ((sub < 0) ? -1 : 0));
}

int charComparator(void *one, void *two, size_t elemSize)
{
   return (*(char *)one) - (*(char *)two);
}

int stringComparator(void *one, void *two, size_t elemSize)
{
   return strcmp(*(char **)one, *(char **)two);
}

int main()
{
   // demostration for sort integer array.
   int unsortedIntegers[] = {1, 4, 2, 8, 5, 7};
   int sortedIntegers[sizeof unsortedIntegers / sizeof(int)];
   int intArraySize = sizeof unsortedIntegers / sizeof(int);

   printf("%-16s: ", "unsorted");
   for(int index = 0; index < intArraySize; index ++)
   {
      printf("%8d", unsortedIntegers[index]);
   }
   printf("\n");

   sortBubbly(unsortedIntegers, sortedIntegers, integerComparator, SD_DESCEND, intArraySize, sizeof(int));
   printf("%-16s: ", "sorted descendly");
   for(int index = 0; index < intArraySize; index ++)
   {
      printf("%8d", sortedIntegers[index]);
   }
   printf("\n");

   sortBubbly(unsortedIntegers, sortedIntegers, integerComparator, SD_ASCEND, intArraySize, sizeof(int));
   printf("%-16s: ", "sorted ascendly");
   for(int index = 0; index < intArraySize; index ++)
   {
      printf("%8d", sortedIntegers[index]);
   }
   printf("\n");

   // demostration for sort float array.
   float unsortedFloats[] = {3.142, 1.414, 1.732, 1.428, 5.714, 0.500};
   float sortedFloats[sizeof unsortedFloats / sizeof(float)];
   int floatArraySize = sizeof unsortedFloats / sizeof(float);
   printf("%-16s: ", "unsorted");
   for(int index = 0; index < floatArraySize; index ++)
   {
      printf("%8.3f", unsortedFloats[index]);
   }
   printf("\n");

   sortBubbly(unsortedFloats, sortedFloats, floatComparator, SD_DESCEND, floatArraySize, sizeof(float));
   printf("%-16s: ", "sorted descendly");
   for(int index = 0; index < floatArraySize; index ++)
   {
      printf("%8.3f", sortedFloats[index]);
   }
   printf("\n");

   sortBubbly(unsortedFloats, sortedFloats, floatComparator, SD_ASCEND, floatArraySize, sizeof(float));
   printf("%-16s: ", "sorted ascendly");
   for(int index = 0; index < floatArraySize; index ++)
   {
      printf("%8.3f", sortedFloats[index]);
   }
   printf("\n");

   // demostration for sort char array.
   char unsortedChars[] = {'k', 'i', 'n', 'g', 'f', 'o', 'x'};
   char sortedChars[sizeof unsortedChars / sizeof(char)];
   int charArraySize = sizeof unsortedChars / sizeof(char);
   printf("%-16s: ", "unsorted");
   for(int index = 0; index < charArraySize; index ++)
   {
      printf("%7c", unsortedChars[index]);
   }
   printf("\n");

   sortBubbly(unsortedChars, sortedChars, charComparator, SD_DESCEND, charArraySize, sizeof(char));
   printf("%-16s: ", "sorted descendly");
   for(int index = 0; index < charArraySize; index ++)
   {
      printf("%7c", sortedChars[index]);
   }
   printf("\n");

   sortBubbly(unsortedChars, sortedChars, charComparator, SD_ASCEND, charArraySize, sizeof(char));
   printf("%-16s: ", "sorted Ascendly");
   for(int index = 0; index < charArraySize; index ++)
   {
      printf("%7c", sortedChars[index]);
   }
   printf("\n");

   // demostration for sort string array.
   char *unsortedStrings[] = {"kingfox", "apple", "ivy", "world", "yuyu", "guoguo"};
   char *sortedStrings[sizeof unsortedStrings / sizeof(char *)];
   int stringArraySize = sizeof unsortedStrings / sizeof(char *);
   printf("%-16s: ", "unsorted");
   for(int index = 0; index < stringArraySize; index ++)
   {
      printf("%8s", unsortedStrings[index]);
   }
   printf("\n");

   sortBubbly(unsortedStrings, sortedStrings, stringComparator, SD_DESCEND, stringArraySize, sizeof (char *));
   printf("%-16s: ", "unsorted");
   for(int index = 0; index < stringArraySize; index ++)
   {
      printf("%8s", sortedStrings[index]);
   }
   printf("\n");

   sortBubbly(unsortedStrings, sortedStrings, stringComparator, SD_ASCEND, stringArraySize, sizeof (char *));
   printf("%-16s: ", "unsorted");
   for(int index = 0; index < stringArraySize; index ++)
   {
      printf("%8s", sortedStrings[index]);
   }
   printf("\n");

   return 0;
}

运行结果如下:

unsorted        :    3.142   1.414   1.732   1.428   5.714   0.500
sorted descendly:    5.714   3.142   1.732   1.428   1.414   0.500
sorted ascendly :    0.500   1.414   1.428   1.732   3.142   5.714
unsorted        :       k      i      n      g      f      o      x
sorted descendly:       x      o      n      k      i      g      f
sorted Ascendly :       f      g      i      k      n      o      x
unsorted        :  kingfox   apple     ivy   world    yuyu  guoguo
unsorted        :     yuyu   world kingfox     ivy  guoguo   apple
unsorted        :    apple  guoguo     ivy kingfox   world    yuyu

这个排序函数之所以可以通用化,有以下原因:

1、sort函数的参数之一是一个比较器函数指针,指向用户自定义的比较器函数。这个比较器函数会比较两个数据的大小,当第一个数据大于第二个数据时,返回正整数;若第一个数据小于第二个数据,返回负整数;若两个数相等,则返回0。

2、sort函数使用无类型指针来指向被排序的数据,并且在形参中给出了被排序数据的空间大小,这样就可以不用在意被排序数据究竟是什么类型。

这个练习涵盖了C语言的数组、指针、字符串、基础数据类型、条件分支、定长循环、标准格式化输出,是个综合性练习。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值