排序算法:冒泡排序

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++)

 

 

<span style="color:#404040;">1.算法是程序的灵魂,优秀的程序在对海量数据处理时,依然保持高速计算,就需要高效的数据结构和算法支撑。</span><br /><br /><span style="color:#404040;">2.网上数据结构和算法的课程不少,但存在两个问题:</span><br /><br /><span style="color:#404040;">1)授课方式单一,大多是照着代码念一遍,数据结构和算法本身就比较难理解,对基础好的学员来说,还好一点,对基础不好的学生来说,基本上就是听天书了</span><br /><span style="color:#404040;">2)说是讲数据结构和算法,但大多是挂羊头卖狗肉,算法讲的很少。 本课程针对上述问题,有针对性的进行了升级 </span><br /><span style="color:#404040;">3)授课方式采用图解+算法游戏的方式,让课程生动有趣好理解 </span><br /><span style="color:#404040;">4)系统全面的讲解了数据结构和算法, 除常用数据结构和算法外,还包括程序员常用10大算法:二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、马踏棋盘算法。可以解决面试遇到的最短路径、最小生成树、最小连通图、动态规划等问题及衍生出的面试题,让你秒杀其他面试小伙伴</span><br /><br /><span style="color:#404040;">3.如果你不想永远都是代码工人,就需要花时间来研究下数据结构和算法。</span><br /><br /><span style="color:#404040;">教程内容:</span><br /><span style="color:#404040;">本教程是使用Java来讲解数据结构和算法,考虑到数据结构和算法较难,授课采用图解加算法游戏的方式。内容包括: 稀疏数组、单向队列、环形队列、单向链表、双向链表、环形链表、约瑟夫问题、栈、前缀、中缀、后缀表达式、中缀表达式转换为后缀表达式、递归与回溯、迷宫问题、八皇后问题、算法的时间复杂度、冒泡排序、选择排序、插入排序、快速排序、归并排序、希尔排序、基数排序(桶排序)、堆排序排序速度分析、二分查找、插值查找、斐波那契查找、散列、哈希表、二叉树、二叉树与数组转换、二叉排序树(BST)、AVL树、线索二叉树、赫夫曼树、赫夫曼编码、多路查找树(B树B+树和B*树)、图、图的DFS算法和BFS、程序员常用10大算法、二分查找算法(非递归)、分治算法、动态规划算法、KMP算法、贪心算法、普里姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法马踏棋盘算法。</span><br /><br /><span style="color:#404040;">学习目标:</span><br /><span style="color:#404040;">通过学习,学员能掌握主流数据结构和算法的实现机制,开阔编程思路,提高优化程序的能力。</span>
相关推荐
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页