close

關於氣泡排序的說明網路上很多,而且這應該是學校必教的項目,所以就不說明了~

如果有需要細項說明的話請參考這裡

為了測試執行的效率,所以設定了一個共1000個值的List給Bubble Sort做處理

第一種方法是過去學校教的,而第二種方法其實看起來沒什麼差,可是執行上出現15ms的差異

一、執行時間約62ms

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import static java.util.Collections.swap;

public class BubbleSort {
  public static void main(String[] args) throws InterruptedException {
    long time1, time2;
    time1 = System.currentTimeMillis();
		
    List list = new ArrayList<>();
		
    for(int i=0; i<1000; i++){
      list.add(new Random().nextInt(1000));
    }
		
    Comparator compar = new Comparator() {
      public int compare(Integer num1, Integer num2) {
	return num1 - num2;
      }	    
    };
		
    bubbleSort(list, compar);
    System.out.println(list);
        
    time2 = System.currentTimeMillis();
    System.out.println((time2-time1) + "/ms");
  }
	
  public static void bubbleSort(List list, Comparator compar) {
    for(int i = 0; i < list.size(); i++) { 
      for(int j = 0; j < list.size() - i - 1; j++) {
        if(compar.compare(list.get(j + 1), list.get(j)) < 0) {
          swap(list, j + 1, j);
        }
      }
    }
  }
}

二、執行時間約47ms

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import static java.util.Collections.swap;

public class BubbleSort {
  public static void main(String[] args) throws InterruptedException {
    long time1, time2;
    time1 = System.currentTimeMillis();
		
    List list = new ArrayList<>();
		
    for(int i=0; i<1000; i++){
      list.add(new Random().nextInt(1000));
    }
		
    Comparator compar = new Comparator() {
      public int compare(Integer num1, Integer num2) {
	return num1 - num2;
      }	    
    };
		
    bubbleSort(list, compar);
    System.out.println(list);
        
    time2 = System.currentTimeMillis();
    System.out.println((time2-time1) + "/ms");
  }
	
  public static void bubbleSort(List list, Comparator compar) {
    for(int i = 0; i < list.size(); i++) { 
      bubbleSwap(list, list.size() - i, compar); 
    }
  }
	
  public static void bubbleSwap(List list, int to, Comparator compar) {
    for(int i = 0; i < to - 1; i++) {
      if(compar.compare(list.get(i + 1), list.get(i)) < 0) {
	swap(list, i + 1, i);
      }
    }
  }
}

但在一些範例中會發現,List中的資料可能排序到一半就排完了,後面的資料雖然都沒有做到交換的動做,但還是一個一個做檢查

為了避免這些不必要的動作,要多加一個檢查,當資料完全沒做到交換的動做時List就視為排序完成並離迴圈

這樣執行的結果平均31~37ms就能執行完成

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import static java.util.Collections.swap;

public class BubbleSort {
  public static void main(String[] args) throws InterruptedException {
    long time1, time2;
    time1 = System.currentTimeMillis();
		
    List list = new ArrayList<>();
		
    for(int i=0; i<1000; i++){
      list.add(new Random().nextInt(1000));
    }
		
    Comparator compar = new Comparator() {
      public int compare(Integer num1, Integer num2) {
	return num1 - num2;
      }	    
    };
		
    bubbleSort(list, compar);
    System.out.println(list);
        
    time2 = System.currentTimeMillis();
    System.out.println((time2-time1) + "/ms");
  }
	
  public static void bubbleSort(List list, Comparator compar) {
    for(int i = 0; i < list.size(); i++) { 
      if(bubbleSwap(list, list.size() - i, compar)) break; 
    }
  }
	
  public static boolean bubbleSwap(List list, int to, Comparator compar) {
    boolean complete = true;
		
    for(int i = 0; i < to - 1; i++) {
      if(compar.compare(list.get(i + 1), list.get(i)) < 0) {
	swap(list, i + 1, i);
	complete = false;
      }
    }
		
    return complete;
  }
}

最後是 Shark Sort 又稱為雙向氣泡排序法

以氣泡排序法為基礎做雙向排序,讓未排序的值集中到 List 中間

而雙向排序會讓中間未排序的部份快速減少,結束的時間自然也就提前了

而 Shark Sort 的執行速度則是穩穩的在31ms上下

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import static java.util.Collections.swap;

public class BubbleSort {
  public static void main(String[] args) throws InterruptedException {
    long start, end;
    start = System.currentTimeMillis();
		
    List list = new ArrayList<>();
		
    for(int i=0; i<1000; i++){
      list.add(new Random().nextInt(1000));
    }
		
    Comparator com = new Comparator() {
      public int compare(Integer num1, Integer num2) {
        return num1 - num2;
      }
    };
		
    sharkSort(list, com);
    System.out.println(list);
        
    end = System.currentTimeMillis();
    System.out.println((end-start) + "/ms");
  }
	
  public static void sharkSort(List list, Comparator com) {
    int left = 0;
    int right = list.size() -1;
    while(left < right){
      right = leftToRight(list, left, right, com);
      left = rightToLeft(list, left, right, com);
    }
    //上面的while也可以改寫成下面的for,但下面這樣的寫法不易閱讀所以不建議這樣寫
    //for(int left = 0, right = list.size() - 1; left < right; right = leftToRight(list, left, right, com), left = rightToLeft(list, left, right, com));
  }
	
  public static int leftToRight(List list, int left, int right, Comparator com) {
    int tag = left;
    for(int i = left; i < right; i++) {
      if(com.compare(list.get(i + 1), list.get(i)) < 0) {
        swap(list, i + 1, i);
        tag = i;
      }
    }
    return tag;
  }
	 
  public static int rightToLeft(List list, int left, int right, Comparator com) {
    int tag = right;
    for(int i = right; i > left; i--) {
      if(com.compare(list.get(i), list.get(i - 1)) < 0) {
        swap(list, i, i - 1);
        tag = i;
      }
    }
    return tag;
  }
}

然而上面的方法只能給型態為 Integer 的資料使用

為了讓程式能夠 reuse,下面將它加入泛型的用法,使它可以排序其它型態的資料,並將 Sort 程式獨立出來

Main:

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

public class SortDemo {
  public static void main(String[] args) {
    List list = new ArrayList<>();
		
    for(int i=0; i<1000; i++){
      list.add(new Random().nextInt(1000));
    }
		
    Comparator com = new Comparator() {
      public int compare(Integer num1, Integer num2) {
	return num1 - num2;
      }
    };
		
    list = new Sort().sharkSort(list, com);
    System.out.println(list);
  }
}

Sort:

import java.util.Comparator;
import java.util.List;
import static java.util.Collections.swap;

public class Sort {
  public <T> List sharkSort(List<T> list, Comparator<? super T> com) {
    int left = 0;
    int right = list.size() -1;
      while(left < right){
        right = leftToRight(list, left, right, com);
	left = rightToLeft(list, left, right, com);
      }
      return list;
  }
	
  private <T> int leftToRight(List<T> list, int left, int right, Comparator<? super T> com) {
    int tag = left;
    for(int i = left; i < right; i++) {
      if(com.compare(list.get(i + 1), list.get(i)) < 0) {
        swap(list, i + 1, i);
        tag = i;
      }
    }
    return tag;
  }
	 
  private <T> int rightToLeft(List<T> list, int left, int right, Comparator<? super T> com) {
    int tag = right;
    for(int i = right; i > left; i--) {
      if(com.compare(list.get(i), list.get(i - 1)) < 0) {
	swap(list, i, i - 1);
	tag = i;
      }
    }
    return tag;
  }
}
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 taurus770423 的頭像
    taurus770423

    Coding Life

    taurus770423 發表在 痞客邦 留言(0) 人氣()