1、算法基本思想
以升序为例,
a.比较前后两个数字,若前者大于后者,则交换两个数字的顺序,反之则不交换;(ps:交换两个数字的顺序)
b.重复上述操作,直到最大的数字“沉”入最右边,最小的数字“浮”在最左边为止。
假如有 N 个数字排序,那么需要比较 N-1 趟,在每一趟的比较中,比较次数有所不同,第 i 趟比较需要比较 N-i 次。
2、源代码
/* * 函数名称:BubbleSort * * 函数功能:冒泡排序(升序)方法1 * * 入口参数:a, len * * 出口参数:无 * * 返回类型:void */ void BubbleSort(int * a, int len) { int i = 0; int j = 0; assert(NULL != a); for (i=0; i<len-1; i++) { for (j=0; j<len-i-1; j++) { if (a[j] > a[j+1]) { a[j] = a[j] ^ a[j+1]; a[j+1] = a[j] ^ a[j+1]; a[j] = a[j] ^ a[j+1]; } else { ; } } } return; }
不足:即使所给数字是有序的,上述算法仍会对其进行一趟又一趟的比较,这样效率太低。
改进:考虑设置一个标志位,假如在某一趟比较中没有发生任何数字的交换,那么说明此刻已经是一个有序的序列,不需要再进行比较了。
首先设置一个标志位 flag = 1,每次进入循环后先把flag置0,假如发生了数字交换,再把flag置1,最后判断flag的值,假如为0则结束循环。
/* * 函数名称:BubbleSort * * 函数功能:冒泡排序(升序)方法2 * * 入口参数:a, len * * 出口参数:无 * * 返回类型:void */ void BubbleSort(int * a, int len) { int i = 0; int j = 0; int flag = 1; assert(NULL != a); while (flag) { flag = 0; for (i=0; i<len-1; i++) { for (j=0; j<len-i-1; j++) { if (a[j] > a[j+1]) { a[j] = a[j] ^ a[j+1]; a[j+1] = a[j] ^ a[j+1]; a[j] = a[j] ^ a[j+1]; flag = 1; } else { ; } } } if (0 == flag) { break; } else { ; } } return; }
不足:代码繁琐,多次判断flag。
改进:考虑在外层循环中同时判断flag以及外层循环变量。
/* * 函数名称:BubbleSort * * 函数功能:冒泡排序(升序)方法3 * * 入口参数:a, len * * 出口参数:无 * * 返回类型:void */ void BubbleSort(int * a, int len) { int i = 0; int j = 0; int flag = 1; assert(NULL != a); for (i=0; (i<len-1) && (flag); i++) { for (j=0; j<len-i-1; j++) { flag = 0; if (a[j] > a[j+1]) { a[j] = a[j] ^ a[j+1]; a[j+1] = a[j] ^ a[j+1]; a[j] = a[j] ^ a[j+1]; flag = 1; } else { ; } } } return; }
当然,也可以使用指针来实现冒泡排序。
/* * 函数名称:BubbleSort * * 函数功能:冒泡排序(升序)方法4 (指针实现) * * 入口参数:pArr, len * * 出口参数:无 * * 返回类型:void */ void BubbleSort(int * pArr, int len) { int * left = pArr; int * right = pArr + len - 1; int * current = pArr; int flag = 1; assert(NULL != pArr); for (left=pArr; (left<right) && (flag); right--) { flag = 0; for (current=pArr; current<right; current++) { if (*current > *(current+1)) { *current = (*current) ^ (*(current+1)); *(current+1) = (*current) ^ (*(current+1)); *current = (*current) ^ (*(current+1)); flag = 1; } else { ; } } } return; }
输入输出函数及主函数
#define _CRT_SECURE_NO_WARNINGS 1 /* * Copyright (c) 2018, code farmer from sust * All rights reserved. * * 文件名称:BubbleSort.c * 功能:冒泡排序算法实现(升序) * * 当前版本:V1.0 * 作者:sustzc * 完成日期:2018年4月4日11:55:48 */ # include <stdio.h> # include <stdlib.h> # include <assert.h> # define ARRAY_LEN 4 /* * 函数名称:Input * * 函数功能:输入数据 * * 入口参数:pNum, length * * 出口参数:无 * * 返回类型:void */ void Input(int * pNum, int length) { int k = 0; if ((NULL != pNum) && (length > 0)) { for (k=0; k<length; k++) { printf("请输入第%d个数字:", k+1); scanf("%d", &pNum[k]); } } else { exit(1); } return; } /* * 函数名称:Output * * 函数功能:输出结果 * * 入口参数:p, le * * 出口参数:无 * * 返回类型:void */ void Output(int * p, int le) { int m = 0; if ((NULL != p) && (le > 0)) { for (m=0; m<le; m++) { printf("%d ", p[m]); } } else { exit(1); } printf("\n"); return; } int main(void) { int arr[ARRAY_LEN] = {0}; Input(arr, ARRAY_LEN); printf("排序之前的数字分别是:\n"); Output(arr, ARRAY_LEN); printf("排序之后的数字分别是:\n"); BubbleSort(arr, ARRAY_LEN); Output(arr, ARRAY_LEN); return 0; }
3、输出结果