排序——冒泡法以及改进、选择法和回调函数采用冒泡的方式模拟实现qsort排序(对任何类型都支持)

【冒泡法】
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

int main()
{
	int arr[] = { 1,2,3,4,5,6 };
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	int temp = 0;
	int j = 0;
	int flag = 0;
	for (i = 0; i < sz-1; i++)
	{
		flag = 0;
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j+1])
			{
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
				flag = 1;
			}
		}
		if (flag == 0)
		{
			break;      //某一轮比较当中没有交换,则整个退出循环
		}
	}	
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	system("pause");
	return 0;
}
【选择法】

算法分析:每趟选出一个最值和无序序列的第一个数交换,n个数共选n-1趟。第i趟假设i为最值下标,然后将最值和i+1至最后一个数比较,找出最值的下标,若最值下标不为初设值,则将最值元素和下标为i的元素交换。

#define _CRT_SECURE_NO_WARNINGS 1  
#include<stdio.h>
#include<stdlib.h>
int main()
{
    int arr[6] = { 1, 0, 6, 1, 8, 2 };
    int i = 0;
    for (i = 0; i < 5; i++)
    {
        int min = i;
        int j = 0;
        int flag = 0;
        for (j = i + 1; j < 6; j++)
        {
            if (arr[min]>arr[j])
            {
                min = j;
            }
            int temp = arr[min];
            arr[min] = arr[i];
            arr[i] = temp;
            flag = 1;
        }
        if (0 == flag)
        {
            break;
        }
    }
    for (i = 0; i < 6; i++)
    {
        printf("%d ", arr[i]);
    }
    system("pause");
    return 0;
}
选择法改进:一次排两个数(最大数和最小数)
#include<stdio.h>
#include<stdlib.h>

void Swap(int *p1, int *p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
}

void SelectSort(int arr[], int len)
{
	int flag = 0;
	int left = 0;
	int right = len-1;
	while (left < right)
	{
		int max = left;
		int min = left;
		int i = left;
		while (i <= right)
		{
			if (arr[i]>arr[max])
				max = i;
			if (arr[i] < arr[min])
				min = i;
			i++;
			flag = 1;
		}

		if (flag == 0)
			break;
		Swap(&arr[left], &arr[min]);
		if (left == max)  //排序特殊情况处理
			max = min;
		Swap(&arr[right], &arr[max]);
		left++;
		right--;
	}
}
void PrintArray(int arr[], int len)
{
	int i = 0;
	for (; i < len; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	int arr[9] = {3,4,2,5,7,8,9,3,5 };
	int size = sizeof(arr) / sizeof(arr[0]);
	PrintArray(arr, size);

	SelectSort(arr, size);
	PrintArray(arr,size);
	system("pause");
	return 0;
}

【回调函数】

1.定义:回调函数就是通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

2.函数可以作为语句,表达式,参数使用(回调函数)。

3.使用qsort函数排序:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

int my_compare(const void *x, const void *y)
{
	if (*(int *)x > *(int *)y)
		return 1;
	else if (*(int *)x < *(int *)y)
		return -1;
	else
		return 0;
}
//my_compare函数返回值大于0,则前者比后者大;
//函数返回值小于0,则后者比前者大;
//返回0,则相等
int main()
{
	int arr[] = { 12, 3, 45, 6, 34, 46, 5, 7, 34, 5, 78 };
	int count = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, count, sizeof(int), my_compare);
	int i = 0;
	/*for (i = 0; i < count; i++)
		printf("%d ", arr[i]);*/
	system("pause");
	return 0;
}
【qsort函数】

原型:

void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );

应用:万能数组排序;

注意事项:

  1. 函数返回类型void;
  2. 函数第一个参数base,类型为void*,含义为所要排序数组的首地址;
  3. 函数第二个参数num,是数组所含元素的个数;
  4. 函数第三个参数width,是数组元素类型所占字节大小;
  5. 函数第四个参数是一个函数指针,返回类型为int,两个参数为const void *,该函数是回调函数;
最主要内容是对compare函数的编写:
  1. compare函数返回值为,正数,则第一个参数比第二个参数大;
  2. 如果返回负数,则第二个参数比第一个参数大;
  3. 如果返回值为0,则两个参数相等;
  4. 套路:强转解引用比较
实例1:对字符串排序

注意:

  1. 定义一个字符指针数组    char *msg[] = { "bbbbb", "aaaaa", "ddddd", "fffff", "zzzzz" };里面每个元素大小为sizeof(char*)而不是5;
  2. 在回调函数里面对两个数组比较需要强转为char**
int cmp(const void *x, const void *y)
{
	return strcmp(*((char **)x), *((char **)y));
}

int main()
{
	char *msg[] = { "bbbbb", "aaaaa", "ddddd", "fffff", "zzzzz" };
	int num = sizeof(msg) / sizeof(msg[0]);
	qsort(msg, num, sizeof(char *), cmp);//观察调试监视
	system("pause");
	return 0;
}
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
int cmp(const void *a,const void *b)  
{  
    return strcmp((char *)a,(char *)b);  
}  
int main()  
{  
    int i;  
    char a[5][10]={"abcd","abc","abcde","feag","fdag"};  
    qsort(a,5,sizeof(a[0]),cmp);  
    for(i=0;i<5;i++)  
    puts(a[i]);  
    return 0;  
}  
实例2:对整数排序
#define _CET_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

int cmp(const void*x, const void *y)
{
	if (*(int *)x > *(int *)y)
		return 1;
	else if (*(int *)x < *(int *)y)
		return -1;
	else
		return 0;
}

int main()
{
	int arr[] = { 3, 4, 2, 6, 7, 1, 8 };
	int size = sizeof(arr) / sizeof(arr[0]);
	qsort(arr, size, sizeof(int), cmp);
	system("pause");
	return 0;
}    

实例3:对结构体数组排序
#include <stdio.h>  
#include <stdlib.h>  
#include <string.h>  
struct node  
{  
    char w[11],d[11];  
}dic[100005];  
int cmp(const void *a,const void *b)  
{  
    return strcmp((*(node *)a).d,(*(node *)b).d);  
}  
int main()  
{  
    int i=0,j;  
    char ch;  
    while(1)  
    {  
        scanf("%s %s",dic[i].d,dic[i].w);  
        getchar(),ch=getchar();  
        i++;  
        if(ch=='\n')  
        break;  
    }  
    qsort(dic,i,sizeof(node),cmp);  
    for(j=0;j<i;j++)  
    printf("%s\n",dic[j].d);  
}  
【模拟实现qsort函数】
#define _CET_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<assert.h>

int int_cmp(const void *x, const void *y)
{
    if (*(int *)x > *(int *)y)
        return 1;
    else if (*(int *)x < *(int *)y)
        return -1;
    else
        return 0;
}

int char_cmp(const void *x, const void *y)
{
    if (*(char *)x > *(char *)y)
        return 1;
    else if (*(char *)x < *(char *)y)
        return -1;
    else
        return 0;
}

int str_cmp(const void *x, const void *y)
{
    return strcmp(*(char **)x, *(char **)y);
}

void swap(char *a1, char *a2,int size)     //按字节交换     
{
    while (size--)
    {
        *a1 ^= *a2;
        *a2 ^= *a1;
        *a1 ^= *a2;
        a1++;
        a2++;
    }
}

void my_qsort(void *base, int num, int size, int(*cmp)(const void *p1, const void *p2))
{
    assert(base);
    int i = 0;
    for (i = 0; i < num - 1; i++)
    {
        int flag = 0;
        int j = 0;
        for (j = 0; j < num - 1 - i; j++)
        {
            if (cmp((char *)base+j*size,(char *)base+(j+1)*size)>0)
            {
                flag = 1;
                swap((char *)base + j*size, (char *)base + (j + 1)*size,size);
            }
        }
        if (0 == flag)
        {
            break;
        }
    }
}

int main()
{
    //整形数组排序
    int arr[] = { 1, 3, 0, 3, 4, 45, 678, 23, 13, 9, 10 };
    int num = sizeof(arr) / sizeof(arr[0]);
    my_qsort(arr, num, sizeof(int), int_cmp);
    int i = 0;
    for (i = 0; i < num; i++)
    printf("%d ", arr[i]);

    //字符串排序
    char arr[] = "ansjdhsfkajakazz123jdk";
    int num = strlen(arr);
    my_qsort(arr, num, sizeof(char), char_cmp);
    printf("%s\n", arr);

    //指针数组元素排序
    char *arr[] = { "vvv", "ssss", "aaa", "cccc", "dddd", "sss" };
    int num = sizeof(arr) / sizeof(arr[0]);
    my_qsort(arr, num, sizeof(char *), str_cmp);
    int i = 0;
    for (i = 0; i < num; i++)
    {
        printf("%s ", arr[i]);
    }
    system("pause");
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_41318405

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值