1. 什么是冒泡排序?(摘抄自百度百科)
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
2. 冒泡排序算法原理(摘抄自百度百科)
② 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
③ 针对所有的元素重复以上的步骤,除了最后一个。
④ 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
3.冒泡排序算法实现(摘抄自百度百科(C语言版))
#include <stdio.h>
#define ARR_LEN 255 /*数组长度上限*/
#define elemType int /*元素类型*/
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
elemType temp;
int i, j;
for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
int main (void) {
elemType arr[ARR_LEN] = {3,5,1,-7,4,9,-6,8,10,4};
int len = 10;
int i;
bubbleSort (arr, len);
for (i=0; i<len; i++)
printf ("%d\t", arr[i]);
putchar ('\n');
return 0;
}
下面进行讲解上面的程序:
1. 定义一个类型为(int)排序数组arr
2. 调用bubbleSort(冒泡排序)函数进行排序数组
3. 通过for循环打印排序完后的数组信息
下面进行讲解关键函数bubbleSort:
/* 冒泡排序 */
/* 1. 从当前元素起,向后依次比较每一对相邻元素,若逆序则交换 */
/* 2. 对所有元素均重复以上步骤,直至最后一个元素 */
/* elemType arr[]: 排序目标数组; int len: 元素个数 */
void bubbleSort (elemType arr[], int len) {
elemType temp;
int i, j;
for (i=0; i<len-1; i++) /* 外循环为排序趟数,len个数进行len-1趟 */
for (j=0; j<len-1-i; j++) { /* 内循环为每趟比较的次数,第i趟比较len-i次 */
if (arr[j] > arr[j+1]) { /* 相邻元素比较,若逆序则交换(升序为左大于右,降序反之) */
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
1. 定义一个类型为(int)的temp临时变量,用于进行数组元素位置之间的交换
2. 定义类型为(int)的i和j,用于数组的外循环和内循环
3. 通过for进行数组的外循环,遍历次数为整个数组的长度
4. 通过for进行数组的内循环,遍历次数为整个数组长度 - 外循环次数
5. 通过if进行比较相邻元素的值,如果后一个元素的值大于当前元素的值则交换两个元素的位置
动画解释
图解:
原始数组
第一次循环
外循环(i)为0, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 0; j++) => for (j=0; j < 9; j++)
外循环(i)为0, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (3 > 5),条件为 false,继续执行
外循环(i)为0, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (5 > 1),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为0, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (5 > -7),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为0, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (5 > 4),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为0, 内循环(j)为4
执行判断, if (arr[j] > arr[j+1]) => if (arr[4] > arr[5]) => if (5 > 9),条件为 false,继续执行
外循环(i)为0, 内循环(j)为5
执行判断, if (arr[j] > arr[j+1]) => if (arr[5] > arr[6]) => if (9 > -6),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为0, 内循环(j)为6
执行判断, if (arr[j] > arr[j+1]) => if (arr[6] > arr[7]) => if (9 > 8),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为0, 内循环(j)为7
执行判断, if (arr[j] > arr[j+1]) => if (arr[7] > arr[8]) => if (9 > 10),条件为 false,继续执行
外循环(i)为0, 内循环(j)为8
执行判断, if (arr[j] > arr[j+1]) => if (arr[8] > arr[9]) => if (10 > 4),条件为 true,执行数组元素交换
交换后的数组
第一次排序结束
第二次排序开始,数组如下。
外循环(i)为1, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 1; j++) => for (j=0; j < 8; j++)
外循环(i)为1, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (3 > 1),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为1, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (3 > -7),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为1, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (3 > 4),条件为 false,继续执行
外循环(i)为1, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (4 > 5),条件为 false,继续执行
外循环(i)为1, 内循环(j)为4
执行判断, if (arr[j] > arr[j+1]) => if (arr[4] > arr[5]) => if (5 > -6),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为1, 内循环(j)为5
执行判断, if (arr[j] > arr[j+1]) => if (arr[5] > arr[6]) => if (5 > 8),条件为 false,继续执行
外循环(i)为1, 内循环(j)为6
执行判断, if (arr[j] > arr[j+1]) => if (arr[6] > arr[7]) => if (8 > 9),条件为 false,继续执行
外循环(i)为1, 内循环(j)为7
执行判断, if (arr[j] > arr[j+1]) => if (arr[7] > arr[8]) => if (9 > 4),条件为 true,执行数组元素交换
交换后的数组
第二次排序结束
第三次排序开始,数组如下。
外循环(i)为2, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 2; j++) => for (j=0; j < 7; j++)
外循环(i)为2, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (1 > -7),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为2, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (1 > 3),条件为 false,继续执行
外循环(i)为2, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (3 > 4),条件为 false,继续执行
外循环(i)为2, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (4 > -6),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为2, 内循环(j)为4
执行判断, if (arr[j] > arr[j+1]) => if (arr[4] > arr[5]) => if (4 > 5),条件为 false,继续执行
外循环(i)为2, 内循环(j)为5
执行判断, if (arr[j] > arr[j+1]) => if (arr[5] > arr[6]) => if (5 > 8),条件为 false,继续执行
外循环(i)为2, 内循环(j)为6
执行判断, if (arr[j] > arr[j+1]) => if (arr[6] > arr[7]) => if (8 > 4),条件为 true,执行数组元素交换
交换后的数组
第三次排序结束
第四次排序开始,数组如下。
外循环(i)为3, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 3; j++) => for (j=0; j < 6; j++)
外循环(i)为3, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > 1),条件为 false,继续执行
外循环(i)为3, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (1 > 3),条件为 false,继续执行
外循环(i)为3, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (3 > -6),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为3, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (3 > 4),条件为 false,继续执行
外循环(i)为3, 内循环(j)为4
执行判断, if (arr[j] > arr[j+1]) => if (arr[4] > arr[5]) => if (3 > 4),条件为 false,继续执行
外循环(i)为3, 内循环(j)为5
执行判断, if (arr[j] > arr[j+1]) => if (arr[5] > arr[6]) => if (4 > 5),条件为 false,继续执行
外循环(i)为3, 内循环(j)为6
执行判断, if (arr[j] > arr[j+1]) => if (arr[6] > arr[7]) => if (5 > 4),条件为 true,执行数组元素交换
交换后的数组
第四次排序结束
第五次排序开始,数组如下。
外循环(i)为4, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 4; j++) => for (j=0; j < 5; j++)
外循环(i)为4, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > 1),条件为 false,继续执行
外循环(i)为4, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (1 > -6),条件为 true,执行数组元素交换
交换后的数组
外循环(i)为4, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (1 > 3),条件为 false,继续执行
外循环(i)为4, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (3 > 4),条件为 false,继续执行
外循环(i)为4, 内循环(j)为4
执行判断, if (arr[j] > arr[j+1]) => if (arr[4] > arr[5]) => if (4 > 4),条件为 false,继续执行
第五次排序结束
第六次排序开始,数组如下。
外循环(i)为5, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 5; j++) => for (j=0; j < 4; j++)
外循环(i)为5, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > -6),条件为 false,继续执行
外循环(i)为5, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (-6 > 1),条件为 false,继续执行
外循环(i)为5, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (1 > 3),条件为 false,继续执行
外循环(i)为5, 内循环(j)为3
执行判断, if (arr[j] > arr[j+1]) => if (arr[3] > arr[4]) => if (3 > 4),条件为 false,继续执行
第六次排序结束
第七次排序开始,数组如下。
外循环(i)为6, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 6; j++) => for (j=0; j < 3; j++)
外循环(i)为6, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > -6),条件为 false,继续执行
外循环(i)为6, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (-6 > 1),条件为 false,继续执行
外循环(i)为6, 内循环(j)为2
执行判断, if (arr[j] > arr[j+1]) => if (arr[2] > arr[3]) => if (1 > 3),条件为 false,继续执行
第七次排序结束
第八次排序开始,数组如下。
外循环(i)为7, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 7; j++) => for (j=0; j < 2; j++)
外循环(i)为7, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > -6),条件为 false,继续执行
外循环(i)为7, 内循环(j)为1
执行判断, if (arr[j] > arr[j+1]) => if (arr[1] > arr[2]) => if (-6 > 1),条件为 false,继续执行
第八次排序结束
第九次排序开始,数组如下。
外循环(i)为8, 内循环(j)为0,数组长度(len)为10
内部循环过滤掉已完成排序的元素, for (j=0; j<len-1-i; j++) => for (j=0; j < 10 - 1 - 8; j++) => for (j=0; j < 1; j++)
外循环(i)为8, 内循环(j)为0
执行判断, if (arr[j] > arr[j+1]) => if (arr[0] > arr[1]) => if (-7 > -6),条件为 false,继续执行
第九次排序结束
排序结束,
排序前的数组
排序后的数组
图解后再看冒泡排序算法原理(摘抄自百度百科)
① 比较相邻的元素。如果第一个比第二个大,就交换他们两个。 if (arr[j] > arr[j+1])
② 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
③ 针对所有的元素重复以上的步骤,除了最后一个。 for (j=0; j<len-1-i; j++)
④ 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。for (i=0; i<len-1; i++)