バブルソートとデータ構造とアルゴリズムの最適化
基本的な紹介
(1)バブルソートの基本的な考え方は、ソートシーケンスを前から後ろに処理し(下付き文字が小さい要素から開始)、
隣接する要素の値を順番に比較し、逆の順序の場合は交換することです。が見つかるので、値が大きくなります。大きな要素は前から後ろに徐々に移動し、水中で泡のように上昇します。
(2)最適化:
各要素はソートプロセス中に常にその位置に近づいているため、比較後に交換がない場合は、シーケンスが正常であることを意味します。したがって
、ソートプロセス中にフラグを設定して、要素が実行されました。交換。これにより、不要な比較を減らすことができます。(ここで説明する最適化
は、バブルソートが記述された後に実行できます)
2つはバブリングプロセスを示しています
上記のグラフィカルプロセスの概要:
(1)配列のサイズに対して合計-1つの大きなループ(n-1)を実行します
(2)各パスのソート数は徐々に減少しています(n-1-i)
(3)一定の選別で交換がない場合は、バブリング選別を早期に終了することができます。これは最適化です
デモコードの実装
/*
// 第一趟排序,就是将第一大的数排在倒数第一位
for (int j = 0; j < arr.length - 1 - 0 ; j++) { // 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第二趟排序,就是将第二大的数排在倒数第二位
for (int j = 0; j < arr.length - 1 - 1 ; j++) { // 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第二趟排序后的数组");
System.out.println(Arrays.toString(arr));
// 第三趟排序,就是将第三大的数排在倒数第三
for (int j = 0; j < arr.length - 1 - 2; j++) { // 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第三趟排序后的数组");
ystem.out.println(Arrays.toString(arr));
// 第四趟排序,就是将第 4 大的数排在倒数第 4 位
for (int j = 0; j < arr.length - 1 - 3; j++) { // 如果前面的数比后面的数大,则交换
if (arr[j] > arr[j + 1]) {
temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
System.out.println("第四趟排序后的数组");
System.out.println(Arrays.toString(arr)); */
}
3つのバブルソートコードの実装
package com.datastrucate.sort;
import java.util.Arrays;
/**
* ClassName:BubbleSort
* Package:com.datastrucate.sort
* Description:
* 冒泡排序及优化
* 思路:两层循环,相邻两数比较大小,n代表数组容量,i代表外部循环次数
* 外部循环次数:n-1,对应比较趟数
* 内部循环次数:n-1-i,对应每趟比较次数
* 空间复杂度:O(n^2)
*
* @Date:2021/3/3 16:08
* @Author:hm
*/
public class BubbleSort {
public static void main(String[] args) {
int[] arr = new int [80000];
//生成8万个随机数
for (int i = 0;i < 80000;i++){
arr[i] = (int)(Math.random()*80000);//范围为[0,80000)
}
long start = System.currentTimeMillis();
System.out.println("排序前时间:"+start+"秒");
bubbleSort(arr);
long end = System.currentTimeMillis();
System.out.println("排序后时间:"+end+"秒");
System.out.println("用时:"+(end-start)+"秒");
}
/**
* 冒泡排序方法
* 外部循环次数:n-1,对应比较趟数
* 内部循环次数:n-1-i,对应每趟比较次数
* @param arr
*/
private static void bubbleSort(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]){
//交换
flag = true;//代表交换了
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
// System.out.println("第"+(i+1)+"趟比较:");
// System.out.println(Arrays.toString(arr));
//每一趟比较后判断flag
if (!flag){
//没有交换过
break;
}else {
//比较过,需重置flag为flase,用于下一趟比较
flag = false;
}
}
}
}