依次对比,大值朝后,每次至少可确定一个当前循环最大值放入最后
public static int[] Bubble_Sort(int[] sourceArray){
if(sourceArray==null || sourceArray.length<2) return sourceArray;
//对原数据进行拷贝
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
for (int i = 1; i < arr.length; i++) { //需要遍历 length-1 次
for(int j=0; j< arr.length-i;j++){ //根据循环次数,每次循环比较次数减1,
if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置,
// 这样当相等时不交换位置保证了稳定性
// 这样可将"最大值"放入本次循环的最后位置
int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
}
}
}
return arr;
}
优化 1/4 加入一个标志位优化一下
public int[] Bubble_Sort_MAX(int[] sourceArray){
if(sourceArray==null || sourceArray.length<2) return sourceArray;
//对原数据进行拷贝
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
for (int i = 1; i < arr.length; i++) {//从第i+1个数向后依次遍历
boolean flag=true;//加入标志位等于 true 表示现在没有 进行换位操作
for(int j=0; j< arr.length-i;j++){
if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
//这样当相等时不交换位置保证了稳定性
// 这样可将"最大值"放入本次循环的最后位置
int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
flag=false;//若在本次循环中进行了换位操作则 设为 false
}
}
if(flag) return arr; //若在某次循环中没有发生依次换位,则说明数组已经有序
}
return arr;
}
优化 2/4 记录有序标记
public int[] Bubble_Sort_MAX2(int[] sourceArray){
if(sourceArray==null || sourceArray.length<2) return sourceArray;
//对原数据进行拷贝
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
int rightMark= arr.length-1;
boolean swopFlag=true;//加入标志位等于 true 表示现在没有 进行换位操作
int temporaryRightMark=0;
for (int i = 1; i < arr.length; i++) {//从第一个数开始
for (int j = 0; j < rightMark; j++) {
if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
//这样当相等时不交换位置保证了稳定性
// 这样可将"最大值"放入本次循环的最后位置
int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
temporaryRightMark=j; //下次循环的结束位置,临时的后面可能继续改变
}
}
if(swopFlag) return arr; //若在某次循环中没有发生依次换位,则说明数组已经有序
rightMark=temporaryRightMark;//在下次循环前将循环的结束位置 赋值
swopFlag=true;//每次循环结束前将下次是否循环的标志重置
}
return arr;
}
优化 3/4 鸡尾酒排序
在没此循环中找到一个最大数和一个最小数,从而只需要循环一半次数 即可将数据排好
这里有一个问题,就是每次排两个那么奇数的时候怎么办呢?
解释:每次排序两个最后剩下的一个刚好是最中间的;
注意一点,在写下面第二次循环的时候别 交换变量时,复制第一次的循环会出错,别问我怎么知道的!!!!
public static int[] Bubble_Sort_MAX3(int[] sourceArray){
if(sourceArray==null || sourceArray.length<2) return sourceArray;
//对原数据进行拷贝
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
boolean swopFlag=true;
for (int i = 0; i < arr.length/2; i++) {//从第一个数开始
for (int j = 0; j < arr.length-i-1; j++) {
if(arr[j]>arr[j+1]){//如果前面的值大于前面的值要置换位置
//这样当相等时不交换位置保证了稳定性
// 这样可将"最大值"放入本次循环的最后位置
int temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
}
}
if(swopFlag) return arr; //若在某次循环中没有换位,则说明数组已经有序
// ----------------------------------------------------------------------
swopFlag=true;//进入前将换位标记重置
for (int j = arr.length-i-1; j >i; j--) {
if(arr[j]<arr[j-1]){//如果后面的值小于前面的值要置换位置
//这样当相等时不交换位置保证了稳定性
// 这样可将"最小值"放入本次循环的最前位置
int temporary=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temporary;
swopFlag=false;//若在本次循环中进行了换位操作则 设为 false
}
}
if(swopFlag) return arr; //若在某次循环中没有换位,则说明数组已经有序
swopFlag=true;//每次循环结束前将下次是否循环的标志重置
}
return arr;
}
优化 4/4 结合鸡尾酒和有序标记
思路: 要比较的数组是中间非最大和最小的,用标记位标记两边已经有序数组,比较中间无序数组
晚上懒得写注释了,中间出错,重写了一波,蛋疼!
public static int[] Bubble_Sort_MAX4(int[] sourceArray){
if(sourceArray==null || sourceArray.length<2) return sourceArray;
//对原数据进行拷贝
int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
int left=0;
int right=arr.length-1;
boolean flag=true;
int temporary;
int temporaryZ = 0;
for (int i = 0; i < arr.length/2; i++) {
for(int j=left; j<right;j++){
if(arr[j]>arr[j+1]){
temporary=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temporary;
flag=false; temporaryZ=j;
}
}
if (flag==true) return arr;
right=temporaryZ;
flag=true;
for (int j=right;j>left;j--){
if (arr[j]<arr[j-1]){
temporary=arr[j]; arr[j]=arr[j-1]; arr[j-1]=temporary;
flag=false;temporaryZ=j;
}
}
if (flag==true)return arr;
left=temporaryZ;
flag=true;
}
return arr;
}