冒泡排序的优化及鸡尾酒排序
首先,我们已经知道了最基本的冒泡排序,可是会有一个问题,就是当排序到一定位置的时候,数组已经有序,可是还是会进行循环,我们该怎么办
这个实现很简单,就是加一个标记,如果已经有序就不用比较了
public static void sort(int[]arrays){
for (int i=0;i<arrays.length-1;i++){
boolean sorts=true;//有序标记,每一轮的初始是true
for (int j=0;j<arrays.length-i-1;j++){
int temp=0;
if(arrays[j]>arrays[j+1]){
temp=arrays[j];
arrays[j]=arrays[j+1];
arrays[j+1]=temp;
sorts=false;
}
}
if(sorts){
break;//如果经历了一整轮的排序后,没有交换,排序完成
}
}
}
第一步的优化完成了,接下来,我们进行第二步优化,如果数组是[3,4,1,2,5,6,7,8]可以看出,后面是有序的,而减少比较次数的方法就是加个有序界定,每轮比较后,记录最后一次元素交换的位置,此位置为无序数组的边界
public static void sort(int array[])
{
int tmp = 0;
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = array.length - 1;
for(int i = 0; i < array.length; i++)
{
boolean isSorted = true;
//有序标记,每一轮的初始是truefor(int j = 0; j < sortBorder; j++)
{
if(array[j] > array[j+1])
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
//把无序数列的边界更新为最后一次交换元素的位置
lastExchangeIndex = j;
}
}
sortBorder = lastExchangeIndex;
if(isSorted){
break;
}
}
}
了解了上面两种排序方式,我们介绍基于冒牌排序的鸡尾酒排序,冒泡排序是单向的比较,而鸡尾酒排序是双向比较,先从左往右比,再右往左比。
例如[2,3,4,5,6,7,8,1]只有1是无序的,首先我们将8和1交换,然后从右往左比较,数组变成[1,2,3,4,5,6,7,8]我们再从左往右比较,有序,结束。只需要三轮
public static void sort(int array[])
{
int tmp = 0;
for(int i=0; i<array.length/2; i++)
{
//有序标记,每一轮的初始是true
boolean 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;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
}
}
if(isSorted){
break;
}//偶数轮之前,重新标记为true
isSorted = 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;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
}
}
if(isSorted){
break;
}
}
}
代码如下
package sort;
import java.util.Arrays;
public class one {
public static void sort(int array[])
{
int tmp = 0;
//记录最后一次交换的位置
int lastExchangeIndex = 0;
//无序数列的边界,每次比较只需要比到这里为止
int sortBorder = array.length - 1;
for(int i = 0; i < array.length; i++)
{
//有序标记,每一轮的初始是true
boolean isSorted = true;
for(int j = 0; j < sortBorder; j++)
{
if(array[j] > array[j+1])
{
tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
//把无序数列的边界更新为最后一次交换元素的位置
lastExchangeIndex = j;
}
}
sortBorder = lastExchangeIndex;
if(isSorted){
break;
}
}
}
public static void main(String[] args){
int[] array = new int[]{3,4,2,1,5,6,7,8};
sort(array);
System.out.println(Arrays.toString(array));
}
}
public class two {
public static void sort(int array[])
{
int tmp = 0;
for(int i=0; i<array.length/2; i++)
{
//有序标记,每一轮的初始是true
boolean 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;
//有元素交换,所以不是有序,标记变为false
isSorted = false;
}
}
if(isSorted){
break;
}
//偶数轮之前,重新标记为true
isSorted = 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;
//有元素交换,所以不是有序,标记变为false
isSorted = 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));
}
}