冒泡排序(Bubble Sorting)的基本思想是:
思路图
由思路图可知
代码实现
注意: 两种方法时间复杂度都是 n^2
package ah.sz.tp.algorithm1.sort;
import java.util.Arrays;
/**
* 冒泡排序法(正序,时间复杂度n^2)
*
* @author TimePause
* @create 2020-01-31 11:46
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = {3, 9, -1, 10, 20};
//int[] arr = {1,2,3,4,5,6};//测试冒泡排序改良是否正确
bubbleSort2(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 冒泡排序法
* 1.需要n-1次大循环
* 2.每个大循环需要比较n-i-1次,作用是将当前循环的一个最大值传到右边
* 3.如果逆序,交换其值;如果都是顺序则直接输出排序结果
*
* @param arr
*/
public static void bubbleSort(int[] arr){
// 用于交换数据的临时变量
int temp=0;
for (int i=0;i<arr.length-1;i++){
for (int j=0;j<arr.length-1-i;j++){
// 正序排序,如果前一个元素大于后一个元素则交换位置
if (arr[j]>arr[j+1]){
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
/*System.out.println("第"+(i+1)+"次排序效果如下");
System.out.println(Arrays.toString(arr));*/
}
}
/**
* 冒泡排序法优化-使用flag
* 1.需要n-1次大循环
* 2.每个大循环需要比较n-i-1次,作用是将当前循环的一个最大值传到右边.例如数组长度为5,第一次循环需要比较4次,第二次并比较需要3次...以此类推
* 3.如果逆序,交换其值;如果都是顺序则直接输出排序结果
*
* @param arr
*/
public static void bubbleSort2(int[] arr){
// 用于交换数据的临时变量
int temp=0;
// 用于标识是否发生了交换
boolean flag=false;
for (int i=0;i<arr.length-1;i++){
for (int j=0;j<arr.length-1-i;j++){
// 正序排序,如果前一个元素大于后一个元素则交换位置
if (arr[j]>arr[j+1]){
// 如果逆序, true
flag=true;
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
}
}
/* System.out.println("第"+(i+1)+"次排序效果如下");
System.out.println(Arrays.toString(arr));*/
if (!flag){//如果flag为false,说明没有发生交换
break;
}else {
//如果发生了交换,需要将flag重新置为false, 防止其在下一个循环异常结束
flag=false;
}
}
}
}
冒泡排序的另一种方法
public static void bubbo(int[] arr) {
int temp = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
}
快速排序法应用实例:
public class QuickSort {
// 时间复杂度 O(nlogn)
public static void quickSort(int[] arr, int left ,int right){
int l= left;//左下标
int r = right;//右下标
int pivot =arr[(left+right)/2];//中轴值
int temp=0;//辅助变量,交换数据时使用
//while循环的作用是让比pivot值小的放在左边,比pivot值大的放在右边
while (l<r){
// 在pivot的左边一直找, 找到大于等于pivot的值才退出
// 作用是找到不符合条件的元素,进行元素交换
while (arr[l]<pivot){
l+=1;//作用是一直找
}
// 在pivot的右边一直找, 找到小于pivot的值才退出
while (arr[r]>pivot){
r -= 1;
}
//如果l>=r,说明指针已经从左边移动找pivot,或者它的右边.因此pivot的左右两的值,已按照规律排序
//即: 左边都是小于pivot的值, 右边都是大于pivot的值
if (l>=r){
break;
}
//交换元素
temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
//如果交换完后,发现这个arr[l] == pivot值 相等 r--, 前移
if(arr[l] == pivot) {
r -= 1;
}
//如果交换完后,发现这个arr[r] == pivot值 相等 l++, 后移
if(arr[r] == pivot) {
l += 1;
}
}
// 如果 l == r, 必须l++, r--, 否则为出现栈溢出
if (l == r) {
l += 1;
r -= 1;
}
//向左递归
if(left < r) {
quickSort(arr, left, r);
}
//向右递归
if(right > l) {
quickSort(arr, l, right);
}
}
public static void main(String[] args) {
int[] arr = {-9, 78, 0, 23, -567, 70};
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
}
测试8w数据排序,用时约为1s以内; 800w数据排序,用时3s左右, 优于希尔排序