バブルソートとデータ構造とアルゴリズムの最適化

バブルソートとデータ構造とアルゴリズムの最適化

基本的な紹介

(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;
            }
        }

    }
}

おすすめ

転載: blog.csdn.net/hcyxsh/article/details/114322079