冒泡函数思路讲解
//一次冒泡排序
#include<string.h>
void bubble(int arr[], int sz)
{
int i = 0;
int j = 0;
for (i = 0; i < sz; i++)
{
for (j =0; j < 9-i ;j++)
{
int a = 0;
if (arr[j] >= arr[j + 1])
{
a = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = a;
}
}
}
}
int main()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d\n", arr[i]);
}
return 0;
}
//优化一下用冒泡函数只能 显示int型
//如何排序结构体数组
struct stu
{
char name[20];
int age;
};
int cmp_int(const void* e1, const void* e2)
{
//用来比较两个整型值的函数
// e1 e2是你需要进行比较的两个元素的地址
//因为不能进行解引用操作
//所以需要用到一个技巧强制类型转换
// *(int*)e1 *(int*)e2
return *(int*)e1 - *(int*)e2;
}
int cmp_float(const void* e1, const void* e2)
{
return((int)( (float)e1 - (float)e2));
}
int main()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1 };
float f[] = { 9.0,8.0, 7.0, 6.0, 5.0, 4.0 };
int sz = sizeof(f) / sizeof(f[0]);
struct stu s[3] = { { "zhangsan",20},{ "lisi",19},{ "wangwu",18} };
//qsort(arr, sz, sizeof(arr[0]),cmp_int );
qsort(f, sz, sizeof(f[0]), cmp_float);
//qsort 数组叫arr 元素个数有sz个 一个元素大小sizeof(arr[0])这么多个字节
//
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%f\n", f[i]);
}
return 0;
//上面的冒泡排序不能排其他数组
}
struct stu
{
char name[20];
int age;
};
int cmp_stu_by_age(const void* e1, const void* e2)
{
//先把e1强制转化成结构体指针类型
return ((struct stu*)e1)->age - ((struct stu*)e2)->age;
}
int main()
{
struct stu s[3] = { { "zhangsan",20},{ "lisi",19},{ "wangwu",18} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]),cmp_stu_by_age );
//上面的冒泡排序不能排其他数组
}
比较名字
//比较名字就是比较字符串
//字符串的比较不能直接用大于小于
//应该用strcmp函数
//return strcmp(((struct stu*)e1)->name - ((struct stu*)e2)->name);
大方向
//void bubble(voidbase , int sz , int width ,int (cmp)())
//开始操作一下
//实现冒泡函数的程序员,他是否知道未来排序的数据类型-不知道
//
void bubble_sort(void base, int sz, int width,int (cmp)(voide1,voide2) )
{
//我要实现比较,那么至少得把比较的方法确定下来
// 并不是简单的大于小于这种 所以我们需要去把另外的比较方法传进去
///还有一点我们需要在cmp后面给上两个参数
/// 我们设计冒泡函数的程序员其实并不知道未来会调用这个函数的数据类型
///
///
///
//最后一个位置是写入实现函数的方法 传入地址 然后在下面调用
//因为我们想返回一个数据告诉我们
//
int i = 0;
//趟数
for (i = 0; i < sz - 1; i++)
{
//每一趟比较的对数
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if ( cmp()>0 ) //两个元素比较
// 交换
}
}
}
void test()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
//当他在进行排序的时候,他只知道了数组从哪里开始,也不知道类型是什么
//那我们把元素的类型 通过别的方式传进去,因为你总不可能传入一个int型 这种
//那我就传入内容宽度
//此处传入一个自己设计的比较函数
bubble_sort(s, sz, sizeof(s[0]), );
}
最后的大思路
我们想要实现一个冒泡函数排序 可以排各种各样的数据
首先我们先写一个main()
然后在内部下一个冒泡函数bubble_sort(arr,sz,sizeof(arr[0]),cmp_int)
void bubble_sort(voidbase,int sz,int wodth,int(cmp)(voide1,voide2))
首先这个函数传过去的数据有
1.数组名(也是首元素地址)
因为传过去类型各不相同 所以不能用自己想法int char这种接收 所以改用void
2.要排序还需要知道元素个数sz
3.元素个数知道了,我们不知道元素是什么类型 用 sizeof(arr[0]) 确定字节
4.第四个是函数的比较方法
ok我们开始实现
for(i=0;i<sz-1;i++)
{
for(j=0;j<sz-1-j;j++)
{
if( )//用if语句来判断
{
完成交换
}
}
}
用if语句判断的时候的窍门
因为我传入的数组可能是整型 可能是浮点型怎么办
那么我们需要一个方法把他们同意在一起
这样的话我们就 自己在引入一个函数
再函数外部完成比较就好了是吧
以后我们其他题目也可以这样 , 在内部的实现比较复杂了,那么我们可以在外部实现
int(cmp)( voide1,voide2)
这是函数指针
我们举一个简单的例子
int cmp_int(const void e1, const void e2)
{
//用来比较两个整型值的函数
// e1 e2是你需要进行比较的两个元素的地址
//因为不能进行解引用操作
//所以需要用到一个技巧强制类型转换
// * (int*)e1 (int)e2
return (int)e1 - (int)e2;
}
int cmp_float(const void* e1, const void* e2)
{
return((int)(* (float*)e1 - (float)e2));
}
区分不同的外部判断之后,我们继续执行if内部的东西
因为函数是指针类型的
所以给e1,e2两个地址
base是我们传过来的首位地址
我们强制类型转化成为char*
(char*)base+jwidth
然后再加字节 因为char是一个字节,我们跳过width个字节长度正好
1 - 2 2 -3 3-4
然后我们分析swap方法
交换传过去地址 再传一下宽度**
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void swap(char* buf1, char* buf2,int width )
{
//这是一个交换函数,交换看上去很简单,但是我们字符类型交换是不是要一个字节一个字节的交换
int i = 0;
for (i = 0; i < width; i++)
{
char*temp = buf1;
*buf1 = *buf2;
*buf2 = temp;
buf1++;
buf2++;
}
}
//void bubble(void*base , int sz , int width ,int (*cmp)())
//开始操作一下
//实现冒泡函数的程序员,他是否知道未来排序的数据类型-不知道
//
void bubble_sort(void* base, int sz, int width,int(*cmp)(void*e1,void*e2))
{
//我要实现比较,那么至少得把比较的方法确定下来
// 并不是简单的大于小于这种 所以我们需要去把另外的比较方法传进去
///还有一点我们需要在cmp后面给上两个参数
/// 我们设计冒泡函数的程序员其实并不知道未来会调用这个函数的数据类型
///
///
///
//最后一个位置是写入实现函数的方法 传入地址 然后在下面调用
//因为我们想返回一个数据告诉我们
//
int i = 0;
//趟数
for (i = 0; i < sz - 1; i++)
{
//每一趟比较的对数
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) //两个元素比较
{
// 交换
swap((char*)base + j * width, (char*)base + (j + 1) * width,width);
}
}
}
}
void test()
{
int s[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(s) / sizeof(s[0]);
//当他在进行排序的时候,他只知道了数组从哪里开始,也不知道类型是什么
//那我们把元素的类型 通过别的方式传进去,因为你总不可能传入一个int型 这种
//那我就传入内容宽度
//此处传入一个自己设计的比较函数
bubble_sort(s, sz, sizeof(s[0]),cmp_int );
}