快速排序实现万能排序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp_char(void *x, void *y);
int cmp_int(void *x, void *y);
int cmp_double(void *x, void *y);
// 通用排序
void quicksort(void *base, unsigned int nmemb, unsigned int size, int (*cmp)(void *, void *));
// 交换值函数
void AssignValue(void *current, void *next, int size);
int main(int argc, const char *argv[]) {
// int数组排序
int arr[10] = {11, 0, 33, 55, 22, 1, 60, 6, 100, 23};
printf("排序前:");
for (int ii = 0; ii < 10; ii++) printf("%d ", arr[ii]);
printf("\n");
quicksort(arr, 10, 4, cmp_int);
printf("排序后:");
for (int ii = 0; ii < 10; ii++) printf("%d ", arr[ii]);
putchar('\xa');
// float数组排序
double arr1[10] = {11.1, 0.8, 33.23, 33.46, 33.5, 44.2, 66.6, 78.9, 90.0, 11.2};
printf("排序前:");
for (int ii = 0; ii < 10; ii++) printf("%.2lf ", arr1[ii]);
printf("\n");
quicksort(arr1, sizeof(arr1) / sizeof(arr1[0]), sizeof(arr1[0]), cmp_double);
printf("排序后:");
for (int ii = 0; ii < 10; ii++) printf("%.2lf ", arr1[ii]);
putchar('\xa');
// 字符数组排序
char arr2[] = "hello world,are you ok?";
printf("排序前:");
for (int ii = 0; ii < 10; ii++)
printf("%c ", arr2[ii]);
quicksort(arr2, strlen(arr2), 1,cmp_char);
for (int ii = 0; ii < 10; ii++)
printf("%c ", arr2[ii]);
printf("排序后:");
putchar('\xa');
// struct数组排序
return 0;
}
// 通用排序函数
// base:待排序内存的首地址
// nmemb:内存中元素的总数量
// size:内存中单个元素的所占字节数
// cmp:函数指针 指向一个返回值为int,形参为void*,void*的函数 (自定义类型排序函数)
void quicksort(void *base, unsigned int nmemb, unsigned int size, int (*cmp)(void *, void *)) {
// 传入的地址为空 或者 数组元素数量少于2个 不必排序
if (base == NULL || nmemb < 2) return;
// 开辟内存空间使用,将基准数(每次取第一次元素为基准数)的值复制到新开辟的空间中
void *flag = malloc(size);
memcpy(flag, base, size);
// 左标杆
unsigned int left = 0;
// 右标杆
unsigned int right = nmemb - 1;
// 获取数组下标为左侧标杆的元素 的地址
char *leftvalue = (char *)base + left * size;
// 获取数组下标为右侧标杆的元素的 地址
char *rightvalue = (char *)base + right * size;
// char* flag1=(char*)base;
// 一轮循环可以将比基准小的元素放到基准元素的左侧 ,大的放到其右边
while (left < right) {
// 右侧标杆 元素如果 大于 基准元素 标杆向前移动即可
while (left < right && cmp(rightvalue, flag) == 1) {
right--;
// 继续获取元素的地址
rightvalue = (char *)base + right * size;
}
// 右侧标杆 元素如果 小于 基准元素 将标杆的值放到左侧标杆的位置
if (left < right) {
// 将右侧标杆值 放到左侧标杆的地址
AssignValue(leftvalue, rightvalue, size);
left++;
leftvalue = (char *)base + left * size;
}
while (left < right && cmp(leftvalue, flag) != 1) {
left++;
leftvalue = (char *)base + left * size;
}
if (left < right) {
AssignValue(rightvalue, leftvalue, size);
right--;
rightvalue = (char *)base + right * size;
}
}
// 将基准元素的值写入内存中
memcpy((char *)base + left * size, flag, size);
free(flag);
flag = NULL;
printf("left=%d\n", left);
/*
測試單一列子(即元素為整形時的數據情況) 排序是否成功
for (int ii = 0; ii < nmemb; ii++) {
printf("%u ", ((int *)base)[ii]);
}
printf("\n");
*/
quicksort((char *)base, left, size, cmp);
quicksort((char *)base + (left + 1) * size, nmemb - left - 1, size, cmp);
}
// 交换地址中值的函数
void AssignValue(void *current, void *next, int size) {
// 边界条件
if (current == NULL || next == NULL || size < 1) return;
memcpy(current, next, size);
}
int cmp_int(void *x, void *y) {
// int *flag=(int*)y;
// int *cur=(int *)x;
// if( *cur > *flag )return 1;
// else return -1;
return (*(int *)x - *(int *)y) > 0 ? 1 : -1;
}
int cmp_double(void *x, void *y) {
return (*(double *)x - *(double *)y) > 0 ? 1 : -1;
}
int cmp_char(void *x, void *y) {
return (*(char *)x - *(char *)y) > 0 ? 1 : -1;
}
冒泡排序实现万能排序:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//通用排序函数
//base:待排序内存的首地址
//nmemb:内存中元素的总数量
//size:内存中单个元素的所占字节数
//cmp:函数指针 指向一个返回值为int,形参为void*,void*的函数 (自定义类型排序函数)
void sort(void* base,unsigned int nmemb,unsigned int size,int(*cmp)(void*,void*));
//交换地址中值的函数
void SwapValue(void *current,void *next,int size);
void Print(void *base,unsigned int len,unsigned int size,const char*flag);
//比较函数
int cmp_int(void*x,void*y);
int cmp_double(void*x,void*y);
int cmp_char(void*x,void*y);
int cmp_stu(void*x,void*y);
//调用结构体比较函数自动比较
int cmp(void*x,void*y);
struct st_girl
{
char name[21];
int age;
};
int main(int argc, const char *argv[])
{
//int数组排序
int arr[10]={11,0,33,55,22,1,60,6,100,23};
printf("排序前:");
Print(arr,10,4,"int");
sort(arr,10,4,cmp_int);
printf("排序后:");
Print(arr,10,4,"int");
putchar('\12');
//double数组排序
double arr1[10]={11.1,0.8,33.23,33.46,33.5,44.2,66.6,78.9,90.0,11.2};
printf("排序前:");
Print(arr1,10,8,"double");
sort(arr1,10,8,cmp_double);
printf("排序后:");
Print(arr1,10,8,"double");
putchar('\12');
//字符数组排序
char arr2[]="hello world,are you ok?";
printf("排序前:");
Print(arr2,strlen(arr2),1,"char");
sort(arr2,strlen(arr2),1,cmp_char);
printf("排序后:");
Print(arr2,strlen(arr2),1,"char");
putchar('\xa');
//struct数组排序
struct st_girl girl[3]={{"aaa",21},{"bbb",19},{"aab",20}};
printf("排序前:\n");
for(int ii=0;ii<3;ii++)
{
printf("name=%s,age=%d\n",girl[ii].name,girl[ii].age);
}
sort(girl,3,sizeof(girl[0]),cmp_stu);
printf("排序后:\n");
for(int ii=0;ii<3;ii++)
{
printf("name=%s,age=%d\n",girl[ii].name,girl[ii].age);
}
return 0;
}
//通用排序函数
//base:待排序内存的首地址
//nmemb:内存中元素的总数量
//size:内存中单个元素的所占字节数
//cmp:函数指针 指向一个返回值为int,形参为void*,void*的函数 (自定义类型排序函数)
void sort(void* base,unsigned int nmemb,unsigned int size,int(*cmp)(void*,void*))
{
if( base==NULL || nmemb<=1 || size<0 || cmp==NULL)return ;
//基于冒泡排序实现的万能排序
for(int ii=0;ii<nmemb-1;ii++)
{
for(int jj=0;jj<nmemb-1-ii;jj++)
{
//当前元素在内存中的位置(在首地址的基础上移动了jj个size字节)
void *cur=(char*)base+jj*size;
//下一元素在内存中的位置
void *next=(char*)base+(jj+1)*(size);
if( cmp(cur,next ))
{
SwapValue(cur,next,size);
}
}
}
}
//交换地址中值的函数
void SwapValue(void *current,void *next,int size)
{
if( current==NULL || next==NULL )return ;
void *pos=malloc(size);
if(pos==NULL)return ;
memcpy(pos,current,size);
memcpy(current,next,size);
memcpy(next,pos,size);
free(pos);pos=NULL;
}
void Print(void *base,unsigned int len,unsigned int size,const char*flag)
{
if( strcmp(flag,"int")==0 )
{
for(int ii=0;ii<len;ii++)
{
printf("%d ",*((int*)(base+(ii*size))));
}
printf("\n");
}
else if(strcmp(flag,"double")==0)
{
for(int ii=0;ii<len;ii++)
{
printf("%.2f ",*((double*)(base+(ii*size))));
}
printf("\n");
}
else if(strcmp(flag,"char")==0)
{
for(int ii=0;ii<len;ii++)
{
printf("%c ",*((char*)(base+(ii*size))));
}
putchar('\xa');
}
}
//整形排序函数
int cmp_int(void*x,void*y)
{
return (*(int*)x-*(int*)y)>0?1:0;
}
//浮点形排序函数
int cmp_double(void*x,void*y)
{
return (*(double*)x-*(double*)y)>0?1:0;
}
//字符形排序函数
int cmp_char(void*x,void*y)
{
return (*(char*)x-*(char*)y)>0?1:0;
}
//结构体排序函数
int cmp_stu(void*x,void*y)
{
return ( ((struct st_girl*)x)->age - ((struct st_girl*)y)->age >0)?1:0;
}