冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。
/**
* 冒泡排序
*
类名:Bubble
* 作者: mht
* 日期: 2018年9月9日-下午6:30:39
*/
public class Bubble {
public static void BubbleSort(int[] arr) {
int temp;
// 冒泡趟数:每循环一趟,就会得出一个最大值
for (int i = 0; i < arr.length - 1; i++) {
// 下标范围:数组长度-每趟已被排序的个数-(不需要再比较的)最后一个数
for (int j = 0; j < arr.length - i - 1; j++) {
// 升序(或降序)
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
public static void main(String[] args) {
int arr[] = { 4, 2, 1, 3, 5 };
Bubble.BubbleSort(arr);
System.out.println(Arrays.toString(arr));
// output : [1, 2, 3, 4, 5]
}
}
不论是冒泡排序还是其他排序方式,都涉及到数字之间的换位。
像通过创建中间值的方式来解决换位问题是最常见也是最简单的实现方法。另外还有两个换位的方式,我来简单说明一下。
这种方法简单来说就是利用两数之和,先加再减。
/* 1、加减换位法*/
int a = 10;
int b = 8;
System.out.println("a = " + a + ", b = " + b);
a = a + b; // 18
b = a - b; // 10
a = a - b; // 8
System.out.println("a = " + a + ", b = " + b);
输出结果:
这种方法利用异或(^)运算,在二进制层面寻求问题的解答方案。
/* 2、异或换位法*/
int x = 10;
int y = 8;
System.out.println("x = " + x + ", y = " + y);
x = x ^ y;
y = x ^ y;
x = x ^ y;
System.out.println("x = " + x + ", y = " + y);
输出结果:
从上面两种不需要中间值的换位法来看,很明显前者“加减换位法”理解起来要简单一些。而第二种“异或换位法”由于采用了二进制层面的运算规则,所以,如果以十进制的角度去寻找它得以解决问题的原因就不那么轻松。所以接下来我们来聊一聊异或运算的规则以及我的一些理解。
异或的规则是:
相异为 1 ,相同为 0
以上面的例子为例。
x = 10 = 1010B
y = 8 = 1000B
根据异或的规则,将两个数按位异或的话,将步骤拆分,可以看到两个数变化的过程:
① x = x ^ y = 1010 ^ 1000 = 0010
② y = x ^ y = 0010 ^ 1000 = 1010 = 10
③ x = x ^ y = 0010 ^ 1010 = 1000 = 8
是不是很神奇?我们在惊叹“异或运算”的强大时,是否应该再来重新审视一下“异或”的概念?
究竟什么是“异或”?从中文的字面上来理解,“异”代表不同、相异;而“或”表示或者、可能,在“异或”的语境下表示前面“异”的另一种可能,即相同。
而实际上,人为规定的 “相异为 1 ,相同为 0” 并不是绝对的,只是一种符合 1 、0 (对、错)概念或习惯的一种标记方式。换句话说,如果我们规定 “相异为0, 相同为 1” ,那么上面的结果依然相同。
// 规定:相异为0, 相同为 1
x = x ^ y = 1010 ^ 1000 = 1101
y = x ^ y = 1101 ^ 1000 = 1010 = 10
x = x ^ y = 1101 ^ 1010 = 1000 = 8
看来,的确如此。
所以,①中两个数按位异或之后,得到的值(0010)并不代表数字(即如果将异或的结果转化为十进制不具有任何意义),而是携带了一个信息,这个信息记录的是这两个数各个位的异同。
这样,②和③的逻辑就不难解释了,数字的每个位遇到1就会变成另一个数(0 变 1,1 变 0);而遇到0则保持不变。就好像在做“找不同”的游戏,先找出不同的位置,然后进行转换。
综上就是关于冒泡排序算法的一些个人见解和实现思路。希望大家文末踊跃留言。