01-冒泡排序代码实现
冒泡排序代码实现及优化
一、算法描述
- 一次比较数组中相邻两元素的大小,若前者大于后者,则交换两个元素,两两都比较一遍称为一轮冒泡,结果是让最大的元素排至最后
- 重复以上步骤,直到整个数组 有序
算法实现---版本一
/**
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrder(int[] myInts){
//外循环控制轮数,内循环控制次数
for (int i = 0; i < myInts.length - 1; i++) {
for (int j = 0; j < myInts.length - 1 - i; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
}
}
}
}
算法实现---版本二
/**
* 优化方式一:如果当一轮中的所有元素都没有交换时,说明该数组已经有序
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion02(int[] myInts){
//额外声明一个布尔变量来记录是否发生交换
boolean swapped = false;
//外循环控制轮数,内循环控制次数
for (int i = 0; i < myInts.length - 1; i++) {
for (int j = 0; j < myInts.length - 1 - i; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
//如果交换了,就修改为true
swapped = true;
}
}
//每一轮结束之后,判断是否数组已经有序
if (!swapped) {
break;
}
}
}
算法实现---版本三
/**
* 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
* 则下一轮的交换只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion03(int[] myInts){
//声明一个变量保存第一轮的需要的交换次数
int first = myInts.length - 1;
//声明一个变量保存每一轮最后交换元素的索引
int last = 0;
//外循环控制轮数,内循环控制次数
while (true) {
//每轮循环之前,需要设置 last为0,否则如果数组有序,而last的值还是上一轮循环的值,
last = 0;
for (int j = 0; j < first; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
last = j;
}
}
//每轮交换结束后设置下一轮需要交换的次数
first = last;
if (first == 0) {
//数组已经有序,直接 退出
break;
}
}
}
交换数组中2个数的代码实现
/**
* 定义一个用于交换数组中2个元素的方法
*
* @param ints 整数数组
* @param i 较大值的索引
* @param j 较小值的索引
*/
public static void swap(int[] ints, int i, int j) {
//采用异或运算实现2个数的交换
ints[i] = ints[i] ^ ints[j];
ints[j] = ints[i] ^ ints[j];
ints[i] = ints[i] ^ ints[j];
}
算法实现---版本三导致死循环的示例
/**
* 错误演示,last设置不合理导致死循环
*
* 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
* 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion04(int[] myInts){
//声明一个变量保存第一轮的需要的交换次数
int first = myInts.length - 1;
//声明一个变量保存每一轮最后交换元素的索引
int last = 0;
//外循环控制轮数,内循环控制次数
while (true) {
//每轮循环之前,需要设置 last为0,否则如果某一轮结束后数组有序(不是在0位置),而last的值还是上一轮循环的值,
//此时last就无法改变,导致无法退出循环
//last = 0;
for (int j = 0; j < first; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
last = j;
}
}
//每轮交换结束后设置下一轮需要交换的次数
first = last;
if (first == 0) {
//数组已经有序,直接 退出
break;
}
}
}
完整代码如下
package org.example.test;
import java.util.Arrays;
/**
* 冒泡排序
*
* @author JIA
* @date 2022/10/07
*/
public class BubbleOrder {
public static void main(String[] args) {
//给定一个测试数组,以整数数组为例
int[] myInts = new int[]{12,5, 3, 7, 2, 1, 9, 8, 4, 11};
//测试排序方法
//bubbleOrder(myInts);
//bubbleOrderVersion02(myInts);
bubbleOrderVersion04(myInts);
System.out.println(Arrays.toString(myInts));
}
/**
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrder(int[] myInts){
//外循环控制轮数,内循环控制次数
for (int i = 0; i < myInts.length - 1; i++) {
for (int j = 0; j < myInts.length - 1 - i; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
}
}
}
}
/**
* 优化方式一:如果当一轮中的所有元素都没有交换时,说明该数组已经有序
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion02(int[] myInts){
//额外声明一个布尔变量来记录是否发生交换
boolean swapped = false;
//外循环控制轮数,内循环控制次数
for (int i = 0; i < myInts.length - 1; i++) {
for (int j = 0; j < myInts.length - 1 - i; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
//如果交换了,就修改为true
swapped = true;
}
}
//每一轮结束之后,判断是否数组已经有序
if (!swapped) {
break;
}
}
}
/**
* 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
* 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion03(int[] myInts){
//声明一个变量保存第一轮的需要的交换次数
int first = myInts.length - 1;
//声明一个变量保存每一轮最后交换元素的索引
int last = 0;
//外循环控制轮数,内循环控制次数
while (true) {
//每轮循环之前,需要设置 last为0,否则如果数组有序,而last的值还是上一轮循环的值,
last = 0;
for (int j = 0; j < first; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
last = j;
}
}
//每轮交换结束后设置下一轮需要交换的次数
first = last;
if (first == 0) {
//数组已经有序,直接 退出
break;
}
}
}
/**
* 错误演示,last设置不合理导致死循环
*
* 优化方式二:每一轮结束后,可能有部分有序的元素,记录下本轮最后一次交换时之前,元素的位置
* 则下一轮的教化只需要进行到这里就可以啦,如果该位置为0,说明数组已经有序
* 实现冒泡排序的方法
*
* @param myInts 需要进行冒泡排序的数组
*/
public static void bubbleOrderVersion04(int[] myInts){
//声明一个变量保存第一轮的需要的交换次数
int first = myInts.length - 1;
//声明一个变量保存每一轮最后交换元素的索引
int last = 0;
//外循环控制轮数,内循环控制次数
while (true) {
//每轮循环之前,需要设置 last为0,否则如果某一轮结束后数组有序(不是在0位置),而last的值还是上一轮循环的值,
//此时last就无法改变,导致无法退出循环
//last = 0;
for (int j = 0; j < first; j++) {
if (myInts[j] > myInts[j + 1]) {
//交换2个元素的位置
swap(myInts, j, j + 1);
last = j;
}
}
//每轮交换结束后设置下一轮需要交换的次数
first = last;
if (first == 0) {
//数组已经有序,直接 退出
break;
}
}
}
/**
* 定义一个用于交换数组中2个元素的方法
*
* @param ints 整数数组
* @param i 较大值的索引
* @param j 较小值的索引
*/
public static void swap(int[] ints, int i, int j) {
//采用异或运算实现2个数的交换
ints[i] = ints[i] ^ ints[j];
ints[j] = ints[i] ^ ints[j];
ints[i] = ints[i] ^ ints[j];
}
}
总结
冒泡排序是一种非常稳定的排序方法,但是遇到一些特殊的数组,反而会减低效率,这个时候就要考虑适当的优化
浙公网安备 33010602011771号