int border = len - 1, lastIndex = 0;
for (int i = 0; i < len; i++) {
boolean isSorted = true;
for (int j = 0; j < border; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
lastIndex = j;
isSorted = false;
}
}
border = lastIndex;
if (isSorted) {
break;
}
}
}
但是,优化第二版仍不是最优方案,上面的两种优化方案只是减少每轮的操作次数,还有一种可以直接减少循环的轮数,那就是鸡尾酒算法排序,请看下面的优化第三版。
三、优化第三版
鸡尾酒算法思想:冒泡排序是元素单向比较,而鸡尾酒排序却是双向。
列举一个最简单的栗子int[] arr = {2, 3, 4, 5, 6, 7, 8, 9, 1};
如果按照传统的冒泡排序进行操作,
第一轮结果:[2, 3, 4, 5, 6, 7, 8, 1, 9],只有9和1交换;
第二轮结果:[2, 3, 4, 5, 6, 7, 1, 8, 9],只有8和1交换;
第三轮结果:[2, 3, 4, 5, 6, 1, 7, 8, 9],只有7和1交换;
。。。
第八轮结果:[1, 2, 3, 4, 5, 6, 7, 8, 9],只有2和1交换;
每一轮执行过程中,前面元素的比较,很明显做了无用功,对于本次栗子中的数组,如果元素比较的顺序是从右边开始,那就省了很多功夫,加入鸡尾酒算法,可以实现这个操作。
鸡尾酒算法实现冒泡排序:
// 优化第三版 (鸡尾酒算法)
public static void bubbleSort4(int[] arr, int len) {
int temp = 0;
boolean isSorted = true;
for (int i = 0; i < len / 2 - 1; i++) {
// 奇数轮比较
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
isSorted = false;
}
}
if (isSorted) {
break;
}
// 偶数轮比较
for (int j = len - i - 1; j > i; j–) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
isSorted = false;
}
}
if (isSorted) {
break;
}
}
}
大循环中我们将循环轮次优化为len/2次,奇数轮比较顺序从左到右,每一轮 j 的开始项也从冒泡算法的0变成了 i ,因为下面还有偶数轮比较排序,偶数轮排序会将最左边的元素变成有序区。
鸡尾酒算法还可以再优化下,于是有了鸡尾酒算法的优化,如下第四版。
四、优化第四版
// 优化第四版 (鸡尾酒算法优化)
public static void bubbleSort5(int[] arr, int len) {
int temp = 0;
boolean isSorted = true;
int lastLeftIndex = 0, lastRightIndex = 0;
//左边界
int leftBorder = 0;
//右边界
int rightBorder = arr.length - 1;
for (int i = 0; i < len / 2 - 1; i++) {
// 奇数轮比较
for (int j = leftBorder; j < rightBorder; j++) {
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
lastRightIndex = j;
isSorted = false;
}
}
rightBorder = lastRightIndex;
if (isSorted) {
break;
}
// 偶数轮比较
for (int j = rightBorder; j > leftBorder; j–) {
if (arr[j] < arr[j - 1]) {
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
lastLeftIndex = j;
isSorted = false;
}
}
leftBorder = lastLeftIndex;
if (isSorted) {
break;
}
}
}
与传统冒泡法的第三版优化一样,设置了每一轮的循环边界,由于鸡尾酒算法是双向排序的,所以这里的边界也分别定义了左、右边界 leftBorder 和 rightBorder ,即每一轮循环都是以这两个边界为循环次数计算,相对于鸡尾酒第一版,第二版比较容易理解。
鸡尾酒算法实现冒泡排序的优化确实可以很大程度上减少了比较的无用功,同时也要注意它的代码量也是之前的两倍。
2020.5.7 更新。。。
对于冒泡排序优化,又想到了一种算法。
// 优化第五版 (引入标志位,只循环一次)
public static void bubbleSort6(int[] arr, int len) {
boolean flag = true;
while (flag) {
flag = false;
for (int i = 0; i < len - 1; i++) {
if (arr[i] > arr[i + 1]) {
int temp = arr[i];
arr[i] = arr[i + 1];
arr[i + 1] = temp;
flag = true;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
架构学习资料
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
JJ5-1713545052599)]
[外链图片转存中…(img-vw55QXJS-1713545052600)]
[外链图片转存中…(img-m8K5BPch-1713545052602)]
[外链图片转存中…(img-jKUBUKT9-1713545052605)]
由于篇幅限制小编,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!