初识C语言之冒泡排序

Posted zsQgqdsd1002

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识C语言之冒泡排序相关的知识,希望对你有一定的参考价值。


前言

冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。

它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。


一、基本思路

首先创建一个循环体,在这个循环体中,不断地比较数组中元素的大小,然后使得最大的元素可以沉到数组的最后一位,然后用另一个循环体套住这个循环体,使得所有的大数都可以沉到数组的下面,小数都可以浮到数组的上面。

二、具体实现

1.冒泡排序1.0

代码如下:

void  Show(int arr[], int len) {
	for (int i = 0; i < len; i++){
		printf("%d\\n", arr[i]);
	}
}//打印数组中所有的元素
void bubberSort(int arr[], int len) {
	for (int i = 0; i < len; i++) 
//总循环趟数,即循环多少趟才能全部排序完毕
	{
		for (int j = 0; j < len - 1; j++)
	//若j == len则会下标越界,所以j < len - 1
	//数组中数字的循环比较,找到一个最大的数字并让其沉下去
	 {
			if (arr[j] > arr[j + 1]) {
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main() {
	int arr[] = { 1,23,31,4 };
	int len = sizeof(arr) / sizeof(arr[0]);
	bubberSort(arr, len);
	Show(arr, len);
}


2.冒泡排序2.0

那么冒泡排序1.0有没有可以优化的地方呢?答案是肯定的,那要从哪里入手进行优化呢?首先可以想到的应该是循环的趟数,对于i来说其实并不需要循环够len趟,其实只需要循环len - 1趟就可以了,因为循环完len - 1趟以后,只剩下一个数字了,那还需要比较吗,显然是不需要的;其次对于j来说,j也并不需要循环len - 1趟,其实j只需要循环len - i - 1趟就可以了,为什么呢,因为每次循环结束后一定会有一个极大值停留在下面,之后上面的值一定不会比这些个极大值大,所以就没有必要在往后循环进行比较了。

代码如下:


冒泡排序2.0   优化循环次数
void  Show(int arr[], int len) {
	for (int i = 0; i < len; i++) {
		printf("%d\\n", arr[i]);
	}
}
void bubberSort(int arr[], int len) {
	for (int i = 0; i < len - 1; i++) {
		for (int j = 0; j < len - 1 - i; j++) {
			if (arr[j] > arr[j + 1]) {
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}
int main() {
	int arr[] = { 1,23,31,4 };
	int len = sizeof(arr) / sizeof(arr[0]);
	bubberSort(arr, len);
	Show(arr, len);
}

3.冒泡排序3.0

那么在2.0 的基础上还可以进行优化吗,当然是可以的。假如说我这个数组一开始就是有序的或者交换一次就有序了呢?用了冒泡排序之后要循环很多次但是我数组本身的元素基本没有发生过改变,再循环就有点麻烦了。所以我们增加一个变量flag,每当程序进入j循环中的if语句时,令flag++,这样的话如果我的程序在整个j循环过程中始终没有进入j循环中的if语句,也就意味着我的数组本身就是有序的,那就直接跳出循环,break。

代码如下:

冒泡排序3.0   优化判断条件
void Show(int arr[], int len) {
	for (int i = 0; i < len; i++) {
		printf("%d\\n", arr[i]);
	}
}
void bubberSort(int arr[], int len) {
	for (int i = 0; i < len - 1; i++) {
		int flag = 0;
		for (int j = 0; j < len - i - 1; j++) {
			if (arr[j] > arr[j + 1]) {
				int tmp = 0;
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag++;
			}
		}
		if (flag == 0) {
			break;
		}
	}
}
int main() {
	int arr[] = { 1,3,8,0,9,1,7,5,6,1,6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	bubberSort(arr, len);
	Show(arr, len);
	return 0;
}

总结

冒泡排序本身并不难,主要是要对其不断的优化,要去思考如何优化,从何入手,这是一种非常不错的思考方式,有时候写出一个程序并不难,难的是如何写出一个好的程序,一个优质的程序,这种不断寻找更优解的思想是我需要学习的。

以上就是我的思考与感悟,如果有可以优化或者有错误的地方,欢迎大佬联系我。

以上是关于初识C语言之冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

C语言之双向冒泡排序

C语言之冒泡排序

一起来学C语言———C语言之冒泡排序和选择排序

C语言之冒泡排序

C语言实用算法系列之冒泡排序sizeof与strlen的区别

C语言试题172之实现冒泡排序算法