package com.example.sort.bubbling;
import java.util.Scanner;
/**
* 9 6 1 3 5
* 6 9 1 3 5
* 6 1 9 3 5
* 6 1 3 9 5
* 6 1 3 5 9
* 第一轮结束 9 从第一位 转移到了最后一位,
* 6 1 3 5 9
* 1 6 3 5 9
* 1 3 6 5 9
* 1 3 5 6 9
* 第二轮结束 9不参与排序,6 从第一位转移到最后一位
* 1 3 5 6 9
* 1 3 5 6 9
* 1 3 5 6 9
* 第三轮结束,6 9 不参与排序
* 1 3 5 6 9
* 1 3 5 6 9
* 第四轮结束 5 6 9不参与排序
* 1 3 5 6 9
* 第五轮结束 3 5 6 9 不参与移动排序
* https://blog.csdn.net/hansionz/article/details/80822494
*/
public class BubblingSort {
public static void main(String[] args) throws Exception {
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = cin.nextInt();
}
System.out.println("开始排序");
System.out.println("排序结果:");
// for (int i : sort1(arr)) {
// System.out.print(i + " ");
// }
// for (int i : sort2(arr)) {
// System.out.print(i + " ");
// }
for (int i : sort3(arr)) {
System.out.print(i + " ");
}
}
/**
* 优化1 使用flag 辅助 可达到最佳O(n)时间复杂度
*
* @param arr
* @return
*/
public static int[] sort1(int[] arr) {
for (int i = 0, len = arr.length - 1, flag = 0; i < len; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
flag = 1;
}
}
if (flag == 0) {
// 如果比较数组就是排序好的,那就不用继续排序
return arr;
}
}
return arr;
}
/**
* 使用服务k记录最后移位的位置
*
* @param arr
* @return
*/
public static int[] sort2(int[] arr) {
int pos = 0;// 记录最后一次交换的位置
for (int i = 0, len = arr.length - 1, k = arr.length - 1, flag = 0; i < len; i++) {
// k 第一次赋值只用了一次
for (int j = 0; j < k; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = temp;
flag = 1; // 标记进行过至少一次的交换元素
pos = j;
}
}
if (flag == 0) {
// 如果比较数组就是排序好的,那就不用继续排序
return arr;
}
k = pos;
}
return arr;
}
/**
* 一次排序决定两个值,,正向扫描找到最大值放到最后,反向扫描找到最小值放到最前面
*
* @param arr
* @return
*/
public static int[] sort3(int[] arr) {
int i = 0;
int j = 0;
int n = 0;//同时找最大最小值需要连个下标遍历
int flag = 0;
int pos = 0;//用来记录最后一次交换的位置
int k = arr.length - 1;
for (i = 0; i < arr.length - 1; i++) {// 确定排序趟数
pos = 0;
flag = 0;
// 正向寻找最大值
for (j = n; j < k; j++) {
if (arr[j] > arr[j + 1]) {
int tep = arr[j + 1];
arr[j + 1] = arr[j];
arr[j] = tep;
flag = 1; // 标记进行过至少一次的交换元素
pos = j; // 交换元素,记录最后一次交换的位置
}
}
if (flag == 0) {
// 如果比较数组就是排序好的,那就不用继续排序
return arr;
}
k = pos;// 下次比较到记录位置即可
// 反向寻找最小值
for (j = k; j > n; j--) {
int tep = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = tep;
flag = 1;
}
n++;
if (flag == 0) {
// 如果比较数组就是排序好的,那就不用继续排序
return arr;
}
}
return arr;
}
}