C语言详解冒泡排序(针对一组无序的数据)

目录

1,冒泡排序原理(图解)

2.冒泡排序实现

3.冒泡排序封装为函数

 

4.冒泡排序代码效率改进。 


核心思想:两两相邻的元素相比较

1,冒泡排序原理(图解)

2.冒泡排序实现

通过图解原理我们可以发现规律(以10个元素排列举例)

1.每一趟比较完全完成就把这一趟数据的最大数放在最后,第一趟是10个数据中的最大值9在最后,第二趟是9个数据中的8在最后,那么我们10个元素就要循环9趟,那么n个数据,就要循环n - 1趟。

2.第一趟是10个数据,就有9对数据比较,那么第二趟,就有8对数据进行比较。如果一趟有n个数据就要比较n - 1对数据。

3.所以需要两层循环,外层控制趟数,内层控制每一趟要比较的次数。

看如下实现。

int main()
{
	int len[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d",&len[i]);
	}
	int n = sizeof(len) / sizeof(len[0]);
	//printf("%d", n);
	int x = 0;
	for (x = 0; x < n; x++)
	{
		int y = 0;
		{
			for (y = 0; y < n-1 - x; y++)
			{
				if (len[y] > len[y + 1])
				{
					int temp = 0;
					temp = len[y];
					len[y] = len[y + 1];
					len[y + 1] = temp;//交换
				}
			}
		}
	}
	
	int j = 0;
	for (j = 0; j < 10; j++)
	{
		printf(" %d ", len[j]);
	}
}

运行结果如图,大家也可以用源码自己体验一下效果: 

 

3.冒泡排序封装为函数

现在已经实现了冒泡排序,为了以后的方便,我们来试着将这个冒泡排序模块功能封装为一个函数。让我们一起来看看自定义为函数有那些坑。

   按照上述排序规则和封装函数的方法,我们将数组作为一个函数参数,传递给冒泡排序函数来执行冒泡排序,我们来看一下: 

void BBurd_sort(int arr[10])
{
	int n= sizeof(arr) / sizeof(arr[0]);
	int x = 0;
	for (x = 0; x < n; x++)
	{
		int y = 0;
		{
			for (y = 0; y < n - 1 - x; y++)
			{
				if (arr[y] > arr[y + 1])
				{
					int temp = 0;
					temp = arr[y];
					arr[y] = arr[y + 1];
					arr[y + 1] = temp;//交换
				}
			}
		}
	}

}
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);
	}
	//int sz = sizeof(arr) / sizeof(arr[0]);
	BBurd_sort(arr);
	int j = 0;
	for (j = 0; j < 10; j++)
	{
		printf(" %d ", arr[j]);
	}
	return 0;
}

我们观察到没有发生排序,我们调试看一下:

问题所在:我们这里想要实现的功能是n 保存的是数组的大小,那么应该是10才对,为什么是2呢。

思考:sizeof(arr[0] 求的是一个整形数组元素的大小那么其大小就应该是4字节,

那么说明我们的sizeof(arr)就是8字节,那么只有可能我们这里的arr,并不是一整个数组,而是一个地址 (地址也就是指针,在32位操作系统下面大小是4个字节,64位操作系统下是8个字节),那就说明我们这里的arr实质上是一个指针,保存的是数组首元素的地址。

所以在函数里面是没有办法求出这个数组的大小,解决办法,把函数的大小作为一个函数的参数一起传递,看一下改进效果。

程序正常实现,附上源码。大家体验一下效果。 

void BBurd_sort(int arr[10], int n)
{
	int x = 0;
		for (x = 0; x < n; x++)
		{
			int y = 0;
			{
				for (y = 0; y < n-1 - x; y++)
				{
					if (arr[y] > arr[y + 1])
					{
						int temp = 0;
						temp = arr[y];
						arr[y] = arr[y + 1];
						arr[y + 1] = temp;//交换
					}
				}
			}
		}

}
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);
	}
	int sz = sizeof(arr) / sizeof(arr[0]);
	BBurd_sort(arr, sz);
		int j = 0;
	for (j = 0; j < 10; j++)
	{
		printf(" %d ", arr[j]);
	}
	return 0;
}

4.冒泡排序代码效率改进。 

思考:

对于这样一个有序数列,我们如果执行的话,我们的自定义函数就还是会跑一遍,那么这样实际效率并不高。所以想能不能改进一下我我们的代码。

再次浏览原理图,我们不难发现这样一个规律,只要数据是乱序一趟下来就会有元素在发生交换。

比如:

9 1 2 3 4 5 6 7 8

这样的数据,第一趟会有元素交换,第二趟就没有。

那么我们可以这样,只要某一趟没有交换,说明此时我们的数列已经有序了就跳出

只要发生交换就继续。

那么看一下改进代码: 

void BBurd_sort(int arr[10], int n)
{
	int x = 0;
		for (x = 0; x < n; x++)
		{
			int flag = 0;
			int y = 0;
			
				for (y = 0; y < n-1 - x; y++)
				{
					if (arr[y] > arr[y + 1])
					{
						int temp = 0;
						temp = arr[y];
						arr[y] = arr[y + 1];
						arr[y + 1] = temp;//交换
						flag = 1;//发生了交换就改变flag
					}
				}
				//执行完一趟就判断一下有没有交换,有交换就继续,没有交换就直接退出,不用排序了
				if (flag == 0)
				{
					break;
				}
			
		}

}
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", &arr[i]);
	}
	int sz = sizeof(arr) / sizeof(arr[0]);
	BBurd_sort(arr, sz);
		int j = 0;
	for (j = 0; j < 10; j++)
	{
		printf(" %d ", arr[j]);
	}
	return 0;
}

  以上就是本期所有的内容,一些关于数组知识大家可以移步到数组文章再进行了解。欢迎大家的批评指正。希望和大家多交流学习。

     和大家一起期待未来更好的自己加油! 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值