java与算法_Java与算法之(1) - 冒泡排序

冒泡排序法的原理是,每次比较相邻的两个元素,如果它们的顺序错误就把它们交换过来。

例如对4 3 6 2 7 1 5这7个数字进行从小到大的排序,从最左侧开始,首先比较4和3

c8efcb4bc1e59ff66e086e317ef25eed.png

因为是从小到大排序,4和3的顺序显然是错误的,交换他们,得到

8fb28926234b58a2b51ca89d6e223384.png

接下来比较4和6

58f4a3541edfa9ad5349128ef65fb63e.png

顺序是正确的,不需要任何操作。接下来进行下一步,比较6和2

70964b36c5b4a29d445ab90c7a57112a.png

6显然应该排在2的后面,怎么办?交换它们,得到

3dd80fa410ec670d0f0a1c6db3a07d1c.png

经过前面几步,已经可以总结出规律,那么接下来要做的比较依次是:

7 > 1? 得到 3 4 2 6 1 7 5

7 > 5? 得到

7d8e09cff75a75dab019592400c532ed.png

到此,7的右边已经没有数可以比较,第一轮排队结束。经过这一轮,已经成功的把最大的数,即7放在了最后。但是前面6个数的顺序还是不对,但是按照上面的思路很容易想到,对前面6个数再来一遍,即可把6放到倒数第二的位置。然后再对前面5个数重复逐个比较的步骤。。。

7个数字需要进行7-1=6次排队,每完成一轮排队,下一轮排队需要比较的数字个数减1,来看代码

public class BubbleSort {

public void sort(int... numbers) {

//n个数执行n-1轮

//每一轮后完成一个数字归位, 下一轮要比较的数字个数减1(所以内层循环是j 

int n = numbers.length - 1;

int t;

for(int i = 0; i 

for(int j = 0; j 

if(numbers[j] > numbers[j + 1]) {

t = numbers[j];

numbers[j] = numbers[j + 1];

numbers[j + 1] = t;

}

}

}

}

}

测试

public static void main(String[] args) {

int[] numbers = new int[]{ 4, 3, 6, 2, 7, 1, 5 };

System.out.print("before: ");

for(int i = 0; i 

System.out.print(numbers[i] + "  ");

}

System.out.println();

new BubbleSort().sort(numbers);

System.out.print("after: ");

for(int i = 0; i 

System.out.print(numbers[i] + "  ");

}

System.out.println();

}

输出

before: 4  3  6  2  7  1  5

after: 1  2  3  4  5  6  7

冒泡排序的核心是两层嵌套的循环,时间复杂度是O(N^2),即对N个数排序,需要近似执行N的平方次。因为效率较低,实际开发中基本不会使用,但是因为简单易懂通常做为学习算法的入门案例。

如果用上面的代码对1 2 3 4 5 6 7做从小到大排列,会发现虽然数字已经排列好,但是程序还是要忠实的执行完全部两层循环。对这种情况,我们可以引入一个变量来记录一次内层循环中交换数字的个数,如果交换个数为0,则提前终止循环,在某些情况下可以提高效率。

public void betterSort(boolean descend, int... numbers) {

System.out.print("before: ");

for(int i = 0; i 

System.out.print(numbers[i] + "  ");

}

System.out.println();

//n个数执行n-1轮

//每一轮后完成一个数字归位, 下一轮要比较的数字个数减1(所以内层循环是j 

int n = numbers.length - 1;

int t;

int flag = 0;

for(int i = 0; i 

for(int j = 0; j 

if(descend) { //从大到小

if(numbers[j] 

t = numbers[j];

numbers[j] = numbers[j + 1];

numbers[j + 1] = t;

flag = 1;

}

} else {

if(numbers[j] > numbers[j + 1]) {

t = numbers[j];

numbers[j] = numbers[j + 1];

numbers[j + 1] = t;

flag = 1;

}

}

}

if(flag == 0) {

break;

} else {

flag = 0;

}

}

System.out.print("after: ");

for(int i = 0; i 

System.out.print(numbers[i] + "  ");

}

System.out.println();

}

增加一个变量需要额外占用内存空间,因此,这个方法是以空间换时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值