万能排序算法(冒泡方法实现和快速排序实现)

快速排序实现万能排序: 

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值