原理介绍
冒泡排序算法的原理如下:
- 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
- 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
- 针对所有的元素重复以上的步骤,除了最后一个。
- 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
流程图示例
代码实现
public static int[] sort1(int[] arr) {
//比较的轮数
for (int j = 0; j < arr.length - 1; j++) {
//每轮比较的次数
for (int i = 0; i < arr.length - 1 - j; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
}
}
}
return arr;
}
优化一
当某一轮排序没有移动任何元素证明已经排好序,直接结束排序。如
{1,2,3,4,5,6,7,8,10,9}
第二轮排序后结束排序
代码实现
//当一轮比较中没有移动元素说明已经排好序,提前结束排序
public static int[] sort2(int[] arr) {
int temp = 0;
boolean flag;//标记是否进行了位置交换
//比较的轮数
for (int j = 0; j < arr.length - 1; j++) {
flag = true;
//每轮比较的次数
for (int i = 0; i < arr.length - 1 - j; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
flag = false;
}
}
if (flag) {
//没有发生位置交换,说明已经排好序
return arr;
}
}
return arr;
}
优化二
每轮排序中记下最后一个交换的位置,则此位置后面的元素已经有序,无需再遍历
代码实现
//通过交换的最后一个元素确定已有序的位置,缩短每轮排序的长度
public static int[] sort3(int[] arr) {
int temp = 0;
int index = arr.length - 1;//当前排序的两个元素中后一个的位置
int temp2 = 0;
boolean flag;//标记是否进行了位置交换
//比较的轮数
for (int j = 0; j < index; j++) {
flag = true;
//每轮比较的次数
for (int i = 0; i < index; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
flag = false;
temp2 = i;
}
}
index = temp2;
if (flag) {
//没有发生位置交换,说明已经排好序
return arr;
}
}
return arr;
}
优化三(双向冒泡排序)
每轮中正向扫描找到最大值交换到最后,反向扫描找到最小值交换到最前面。例如:
{1,2,3,4,5,6,0}
代码实现
//一轮排序中,从前向后将最大元素移到最后,从后向前将最小元素移到最前
public static int[] sort4(int[] arr) {
int left = 0;//未排序元素中最小下标
int right = arr.length - 1;//未排序元素中最大下标
int index_left = left;//从后向前排序中发生位置移动的两个元素中后一个元素下标
int index_right = right;//从前向后排序中发生位置移动的两个元素中前一个元素下标
int temp = 0;
boolean flag;//标记是否进行了位置交换
//最小下标与最大下标重合,排序结束
while (left < right) {
flag = true;
//从前向后排出最大
for (int i = left; i < right; i++) {
if (arr[i] > arr[i + 1]) {
temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
flag = false;
index_right = i;
}
}
right = index_right;
//从后向前排出最小
for (int i = right; i > left; i--) {
if (arr[i] < arr[i - 1]) {
temp = arr[i];
arr[i] = arr[i - 1];
arr[i - 1] = temp;
flag = false;
index_left = i;
}
}
left = index_left;
if (flag) {
//没有发生位置交换,说明已经排好序
return arr;
}
}
return arr;
}