一、冒泡排序函数
1.思路讲解
冒泡排序思想:两两相邻的数进行比较,有可能需要交换。
例:假设有5个数:5 3 4 2 1 ,要对其进行升序排列。
思路如下:
5-3 4 2 1(5>3,交换位置)
3 5-4 2 1(5>4,交换位置)
3 4 5-2 1(5>2,交换位置)
3 4 2 5-1(5>1,交换位置)
3 4 2 1 5(此时,经过第一轮4对数的比较,5已经到达正确的位置,接下来5不动)
接着
进行第二轮的比较
3-4 2 1 5(3<4,不动)
3 4-2 1 5(4>2,交换位置)
3 2 4-1 5(4>1,交换位置)
3 2 1 4 5 (此时,经过第二轮3对数的比较,4也已经到达正确位置)
接着
以此类推,进行第三轮2对数的比较、第四轮1对数的比较,就可以完成排序。
由上面的例子分析可知,第一轮有4对数进行比较,第二轮有3对,第三轮有2对,第二轮有1对,5个数进行排序时,需进行4轮,
n个数进行排序时,则需进行n-1轮。第n轮有n-1对数要比较
2.错误设计
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void bubble_sort(int arr[])
{
int sz = sizeof(arr)/ sizeof(arr[0]);//这样对吗?
int i = 0;
for (i = 0; i < sz-1; i++)//控制轮
{
int j = 0;
for (j = 0; j < sz-i-1; j++)//控制对
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = {5,3,4,2,1};
bubble_sort(arr);//是否可以正常排序?
int i = 0;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d", arr[i]);
}
return 0;
}
运行上面的代码时,我们发现,打印出来的数并没有排序成功,并且通过监视发现,sz的值是1,为什么呢?我们先来了解一下数组名究竟是什么吧。
二、数组名是什么?
在大多数时候,数组名是首元素地址,但有两个例外:
1.sizeof(数组名):计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组。
2.&数组名:取出的是数组的地址。&数组名,数组名表示整个数组。
1.printf(“%p”, arr);
2.printf(“%p”, &arr[0]);
3.printf(“%p”, &arr);
虽然上面三种情况打印的值虽然相同,但1/2和3的意义完全不同。
1.printf(“%p”, arr+1);
跳过的是一个元素(4byte)
2.printf(“%p”, &arr[0]+1);
跳过的是一个元素(4byte)
3.printf(“%p”, &arr+1);
跳过的是一整个数组
回到刚刚的错误设计,错误原因就在于把数组名传给了函数,也就是把第一个元素的地址传给了函数,
因此sz = sizeof(arr)/ sizeof(arr[0])=1
正确设计
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
void bubble_sort(int arr[],int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[] = { 5,3,4,2,1 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
int i = 0;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
你学废了吗?bye~