漫画:什么是鸡尾酒排序

转载自   漫画:什么是鸡尾酒排序

那么,鸡尾酒排序又是何方神圣呢?我们这一期将会详细讲述。

让我们首先来回顾一下冒泡排序的思想:

冒泡排序的每一个元素都可以像小气泡一样,根据自身大小,一点一点向着数组的一侧移动。算法的每一轮从都是从左到右比较元素,进行单向的位置交换

那么鸡尾酒排序做了怎样的优化呢?

鸡尾酒排序的元素比较和交换过程是双向的。

让我们来举一个栗子:

有8个数组成一个无序数列:2,3,4,5,6,7,8,1,希望从小到大排序。

如果按照冒泡排序的思想,排序的过程是什么样呢?

第一轮结果(8和1交换)

第二轮结果(7和1交换)

 

第三轮结果(6和1交换)

 

第四轮结果(5和1交换)

第五轮结果(4和1交换)

 

第六轮结果(3和1交换)

第七轮结果(2和1交换)

 

鸡尾酒排序是什么样子呢?让我们来看一看详细过程:

第一轮(和冒泡排序一样,8和1交换)

第二轮

此时开始不一样了,我们反过来从右往左比较和交换:

8已经处于有序区,我们忽略掉8,让1和7比较。元素1小于7,所以1和7交换位置:

接下来1和6比较,元素1小于6,所以1和6交换位置:

接下来1和5比较,元素1小于5,所以1和5交换位置:

接下来1和4交换,1和3交换,1和2交换,最终成为了下面的结果:

第三轮(虽然已经有序,但是流程并没有结束)

鸡尾酒排序的第三轮,需要重新从左向右比较和交换:

1和2比较,位置不变;2和3比较,位置不变;3和4比较,位置不变......6和7比较,位置不变。

没有元素位置交换,证明已经有序,排序结束。

这就是鸡尾酒排序的思路。排序过程就像钟摆一样,第一轮从左到右,第二轮从右到左,第三轮再从左到右......

public class CockTailSort {private static void sort(int array[]){int tmp  = 0;for(int i=0; i<array.length/2; i++) {//有序标记,每一轮的初始是trueboolean isSorted = true;//奇数轮,从左向右比较和交换for(int j=i; j<array.length-i-1; j++){if(array[j] > array[j+1]){tmp = array[j];array[j] = array[j+1];array[j+1] = tmp;//有元素交换,所以不是有序,标记变为falseisSorted = false;}}if(isSorted){break;}//偶数轮之前,重新标记为trueisSorted = true;//偶数轮,从右向左比较和交换for(int j=array.length-i-1; j>i; j--) {if(array[j] < array[j-1]){tmp = array[j];array[j] = array[j-1];array[j-1] = tmp;//有元素交换,所以不是有序,标记变为falseisSorted = false;}}if(isSorted){break;}}
}public static void main(String[] args){int[] array = new int[]{2,3,4,5,6,7,8,1};sort(array);System.out.println(Arrays.toString(array));
}
}

这段代码是鸡尾酒排序的原始实现。代码外层的大循环控制着所有排序回合,大循环内包含两个小循环,第一个循环从左向右比较并交换元素,第二个循环从右向左比较并交换元素。

 

让我们来回顾一下冒牌排序针对有序区的优化思路:

 

原始的冒泡排序,有序区的长度和排序的轮数是相等的。比如第一轮排序过后的有序区长度是1,第二轮排序过后的有序区长度是2 ......

要想优化,我们可以在每一轮排序的最后,记录下最后一次元素交换的位置,那个位置也就是无序数列的边界,再往后就是有序区了。

对于单向的冒泡排序,我们需要设置一个边界值,对于双向的鸡尾酒排序,我们需要设置两个边界值。请看代码:

public class CockTailSort {private static void sort(int array[]){int tmp  = 0;//记录右侧最后一次交换的位置int lastRightExchangeIndex = 0;//记录左侧最后一次交换的位置int lastLeftExchangeIndex = 0;//无序数列的右边界,每次比较只需要比到这里为止int rightSortBorder = array.length - 1;//无序数列的左边界,每次比较只需要比到这里为止int leftSortBorder = 0;for(int i=0; i<array.length/2; i++){//有序标记,每一轮的初始是trueboolean isSorted = true;//奇数轮,从左向右比较和交换for(int j=leftSortBorder; j<rightSortBorder; j++){if(array[j] > array[j+1]){tmp = array[j];array[j] = array[j+1];array[j+1] = tmp;//有元素交换,所以不是有序,标记变为falseisSorted = false;lastRightExchangeIndex = j;}}rightSortBorder = lastRightExchangeIndex;if(isSorted){break;}//偶数轮之前,重新标记为trueisSorted = true;//偶数轮,从右向左比较和交换for(int j=rightSortBorder; j>leftSortBorder; j--){if(array[j] < array[j-1]){tmp = array[j];array[j] = array[j-1];array[j-1] = tmp;//有元素交换,所以不是有序,标记变为falseisSorted = false;lastLeftExchangeIndex = j;}}leftSortBorder = lastLeftExchangeIndex;if(isSorted){break;}}
}public static void main(String[] args){int[] array = new int[]{2,3,4,5,6,7,8,1};sort(array);System.out.println(Arrays.toString(array));
}
}

代码中使用了左右两个边界值,rightSortBorder 代表右边界,leftSortBorder代表左边界。 

在比较和交换元素时,奇数轮从 leftSortBorder 遍历到 rightSortBorder 位置,偶数轮从 rightSortBorder 遍历到 leftSortBorder 位置。

  

  

    

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/325986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018蓝桥杯省赛---java---A---10(付账问题)

题目描述 思路分析 用贪心算法&#xff0c;要使标准差最小&#xff0c;则需要将每个人需付的钱接近于平均值。如果有人的钱低于当前平均值a1&#xff0c;则需要将这人的钱全部支付&#xff0c;此人不够的钱需让其他人付&#xff0c;然后可以计算剩余人所需付钱的平均值a2&…

想要学习设计模式,你得先会看类图,一张图读懂UML

虚线箭头指向依赖&#xff1b; 实线箭头指向关联&#xff1b; 虚线三角指向接口&#xff1b; 实线三角指向父类&#xff1b; 空心菱形能分离而独立存在&#xff0c;是聚合&#xff1b; 实心菱形精密关联不可分&#xff0c;是组合&#xff1b;

数据库的这些性能优化,你做了吗

转载自 数据库的这些性能优化&#xff0c;你做了吗 在互联网项目中&#xff0c;当业务规模越来越大&#xff0c;数据也越来越多&#xff0c;随之而来的就是数据库压力会越来越大。 我们可能会采取各种方式去优化&#xff0c;比如之前文章提到的缓存方案&#xff0c;SQL优化…

青客宝团队Consul内部分享ppt

Consul 是一个支持多数据中心&#xff0c;分布式&#xff0c;高可用的服务发现和配置共享系统。由 HashiCorp 公司使用 Go 语言开发&#xff0c;基于Raft协议。部署起来非常容易&#xff0c;只需要极少的可执行程序和配置文件&#xff0c;具有绿色、轻量级的特点。 Consul是支持…

2018蓝桥杯省赛---java---C---9(小朋友崇拜圈)

题目描述 思路分析 数组来储存小朋友们的崇拜对象&#xff0c;然后下标1就是对应的小朋友座号&#xff0c;写一个方法找出每一个小朋友的崇拜圈大小&#xff0c;然后找出最大的崇拜圈即可 代码实现 package lanqiao;import java.util.*;public class Main {public static vo…

漫画:什么是时间复杂度

转载自 漫画&#xff1a;什么是时间复杂度 时间复杂度的意义 究竟什么是时间复杂度呢&#xff1f;让我们来想象一个场景&#xff1a; 某一天&#xff0c;小灰和大黄同时加入了一个公司...... 一天过后&#xff0c;小灰和大黄各自交付了代码&#xff0c;两端代码实现的功能…

Visual Studio 和 Team Foundation Server 产品维护及周期策略

1 适用于 Visual Studio 和 Team Foundation Server 2012 - 2017 这些产品遵循 Microsoft 10 年支持生命周期策略&#xff08;5 年主流支持和 5 年扩展支持&#xff09;&#xff0c;起始日期为主要产品版本向全球 (RTW) 发布的日期。 例如&#xff0c;Visual Studio 2017 于 20…

28. 实现 strStr()---LeetCode---JAVA(今天又是一行超人)

class Solution {public int strStr(String haystack, String needle) {return haystack.indexOf(needle);} }

DevOps通用及版本控制面试题

转载自 DevOps通用及版本控制面试题 通用DevOps面试问题 此类别将包含与任何特定DevOps阶段无关的问题。这里的问题旨在测试您对DevOps的理解&#xff0c;而不是关注特定工具或阶段。 问题一&#xff1a; DevOps和Agile之间的根本区别是什么&#xff1f; 两者之间的差异…

微信和支付宝支付模式详解及实现(.Net标准库)

支付基本上是很多产品都必须的一个模块&#xff0c;大家最熟悉的应该就是微信和支付宝支付了&#xff0c;不过更多的可能还是停留在直接sdk的调用上&#xff0c;甚至和业务系统高度耦合&#xff0c;网上也存在各种解决方案&#xff0c;但大多形式各异&#xff0c;东拼西凑而成。…

.NET遇上Docker - 使用Docker Compose组织Ngnix和.NETCore运行

本文工具准备&#xff1a; Docker for WindowsVisual Studio 2015 与 Visual Studio Tools for Docker或 Visual Studio 2017 需要在安装时选择“容器开发支持”&#xff0c;如图&#xff1a; Docker的思想是将不同的应用放在不同的容器中分开运行&#xff0c;如运行.NetCore …

为什么大公司一定要使用DevOps

转载自 为什么大公司一定要使用DevOps 0 DevOps的意图 究竟什么是DevOps? 要想回答这个问题&#xff0c;首先要明确DevOps这个过程参与的人员是谁&#xff1f;即开发团队和IT运维团队&#xff01;那么&#xff0c;DevOps的意图是什么呢&#xff1f;即在两个团队之间&#…

怎样访问Springboot项目中static中的资源

第一步 成功启动 第二步 输入 协议://ip:端口/资源的名字 eg http://localhost:8080/06-demo-point.html

asp.net core源码飘香:Logging组件

简介&#xff1a; 作为基础组件&#xff0c;日志组件被其他组件和中间件所使用&#xff0c;它提供了一个统一的编程模型&#xff0c;即不需要知道日志最终记录到哪里去&#xff0c;只需要调用它即可。 使用方法很简单&#xff0c;通过依赖注入ILogFactory&#xff08;CreateL…

互联网账户系统如何设计

转载自 互联网账户系统如何设计 在很多互联网公司业务发展的早期&#xff0c;业务模式比较单一的情况下&#xff0c;涉及用户账户资金交易相关的逻辑也比较简单&#xff0c;但是随着公司业务模式的不断创新及类型的多元化发展&#xff0c;会渐渐发现现有系统账户逻辑越来越雍…

数组(ArrayList)底层怎样扩容

ArrayList维护了数组transient Object[] elementData; 初始化 数组需要扩容时

Visual Basic 15语言新特性

对于C#的两个重要特性元组和Ref返回值&#xff0c;Visual Basic 15提供了对等的实现。这两个特性都是“不完全的”&#xff0c;但已经可以提供足够的变通方案&#xff0c;让VB应用程序可以消费使用了这些特性的C#库。 元组 在VB中&#xff0c;从单个函数调用直接返回多个值是…

Struts2面试问题

转载自 Struts2面试问题 1.什么是Struts2&#xff1f; Apache Struts2是一个用Java构建Web应用程序的开源框架。Struts2基于OpenSymphony WebWork框架。它从Struts1中得到了很大的改进&#xff0c;使其更加灵活&#xff0c;易于使用和扩展。Struts2的核心组件是Action&…

谷歌工程师文化中的几个核心原则

转载自 谷歌工程师文化中的几个核心原则 每周&#xff0c;一组谷歌员工都会在厕所的墙壁上粘贴一页来分享本周的测试小建议。有时这页纸会讨论依赖注入&#xff0c;并提供一个简单的示例展示如何用不同语言使用它&#xff1b;有时它可能会分享如何安装一个用于测量团队代码库…

初探CSRF在ASP.NET Core中的处理方式

前言 前几天&#xff0c;有个朋友问我关于AntiForgeryToken问题&#xff0c;由于对这一块的理解也并不深入&#xff0c;所以就去研究了一番&#xff0c;梳理了一下。 在梳理之前&#xff0c;还需要简单了解一下背景知识。 AntiForgeryToken 可以说是处理/预防CSRF的一种处理…