2016/1/10 三種排序方法 二分法排序 快速排序 冒泡排序


//排序和查找是數據結構與算法設計的重要內容
/*
排序主要包括
1.插入排序:又包括直接插入排序、二分法插入排序、表插入排序、Shell排序
2.選擇排序:包括直接選擇排序、堆排序
3.交換排序:冒泡排序、快速排序
4.分配排序:主要有基數排序
5.歸並排序:主要有內排序、外排序
注:以下程序均在本人電腦上通過完整的數據測試
*/
/////////////////////////////////////////////////////////
/////////////1.冒泡排序//////////////////////////////////
/////////////////////////////////////////////////////////
/*算法分析:

依次比較相鄰的兩個數,將大數放在前面,小數放在后面。
即首先比較第1個和第2個數,將大數放前,小數放后。然
后比較第2個數和第3個數,將大數放前,小數放后,如此
繼續,直至比較最后兩個數,將大數放前,小數放后,此
時第一趟結束,在最后的數必是所有數中的最小數。重復
以上過程,仍從第一對數開始比較(因為可能由於第2個數
和第3個數的交換,使得第1個數不再大於第2個數),將大
數放前,小數放后,一直比較到最小數前的一對相鄰數,
將大數放前,小數放后,第二趟結束,在倒數第二個數中得
到一個新的最小數。如此下去,直至最終完成排序。
*/
public class MaoPao {
public void BubbleSort(int a[]) {
  int temp = 0;
  for (int i = 0; i < a.length; i++) {
    for (int j = 0; j < a.length - i - 1; j++) {
    if (a[j] > a[j + 1]) {
      temp = a[j];
      a[j] = a[j + 1];
      a[j + 1] = temp;
}
}
}
  for (int item : a) {
    System.out.println(item);
}
}
public static void main(String[] args) {
MaoPao mp = new MaoPao();
int[] a = { 49, 38, 65, 97, 76, 13, 27 };
mp.BubbleSort(a);
}
}

/////////////////////////////////////////////////////////
/////////////2.快速排序//////////////////////////////////
/////////////////////////////////////////////////////////
/**算法分析:
*
* 快速排序對冒泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的
* 兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分
* 數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
*
* 設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用第一個數據)作為關鍵
* 數據,然后將所有比它小的數都放到它前面,所有比它大的數都放到它后面,這個過程稱為一
* 躺快速排序。一躺快速排序的算法是:
  1)設置兩個變量I、J,排序開始的時候:I=0,J=N-1;
  2)以第一個數組元素作為關鍵數據,賦值給X,即 X=A[0];
  3)從J開始向前搜索,即由后開始向前搜索(J=J-1),找到第一個小於X的值,讓該值與X交換;
  4)從I開始向后搜索,即由前開始向后搜索(I=I+1),找到第一個大於X的值,讓該值與X交換;
  5)重復第3、4步,直到 I=J;
  例如:待排序的數組A的值分別是:(初始關鍵數據:X=49)
  A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:
   49 38 65 97 76 13 27
  進行第一次交換后: 27 38 65 97 76 13 49
  ( 按照算法的第三步從后面開始找)
  進行第二次交換后: 27 38 49 97 76 13 65
  ( 按照算法的第四步從前面開始找>X的值,65>49,兩者交換,此時:I=3 )
  進行第三次交換后: 27 38 13 97 76 49 65
  ( 按照算法的第五步將又一次執行算法的第三步從后開始找
  進行第四次交換后: 27 38 13 49 76 97 65
  ( 按照算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時:J=4 )
  此時再執行第三步的時候就發現I=J,從而結束一躺快速排序,那么經過一趟快速排序之后的結果是:
27 38 13 49 76 97 65,即所以大於49的數全部在49的后面,所以小於49的數全部在49的前面。
  快速排序就是遞歸調用此過程——在以49為中點分割這個數據序列,分別對前面一部分和后面一部分
進行類似的快速排序,從而完成全部數據序列的快速排序,最后把此數據序列變成一個有序的序列,
根據這種思想對於上述數組A的快速排序的全過程如圖6所示:
  初始狀態 {49,38,65,97,76,13,27}
  進行一次快速排序之后划分為 {27 38 13} 49 {76 97 65}
  分別對前后兩部分進行快速排序 {27 38 13} 經第三步和第四步交換后變成 {13 27 38} 完成排序。
  {76 97 65} 經第三步和第四步交換后變成 {65 76 97} 完成排序。
*
*/

public class QuickSort {
public int partition(int[] a, int i, int j) {//分割排序
  int key = a[i];
    while(i < j) {
      while(i < j && a[j] >= key) //找出第一個比key小,並記下j值
      j--;
      a[i] = a[j];//將a[j]移至a[i]處
    while(i < j && a[i] <= key)//找出第一個比key大,並記下i值
      i++;
      a[j] = a[i];//將a[i]移至a[j]處
}
  a[i] = key;//此時完成一趟排序
  return i;//此時i=j,記下i的值
}

  public void sort(int[] a, int i, int j) {//遞歸調用分割
    if(i < j) {
      int n = partition(a,i,j);//排一次序列,並獲取關鍵值的位置
      sort(a,i,n-1);//左遞歸
      sort(a,n+1,j);//右遞歸
}
}
public static void main(String[] args) {
  int[] a = {49,38,65,97,76,13,27};
    new QuickSort().sort(a, 0, 6);
    for(int item : a) {
    System.out.println(item);
}
}

}


/////////////////////////////////////////////////////////
/////////////3.折半(二分)法查找////////////////////////
/////////////////////////////////////////////////////////
/**算法分析
*
* 將數列按有序化(遞增或遞減)排列,查找過程中采用跳躍式方式查找,
* 即先以有序數列的中點位置為比較對象,如果要找的元素值小於該中
* 點元素,則將待查序列縮小為左半部分,否則為右半部分。通過一次
* 比較,將查找區間縮小一半。
  折半查找是一種高效的查找方法。它可以明顯減少比較次數,提高查
找效率。但是,折半查找的先決條件是查找表中的數據元素必須有序。

* 雖然二分(折半)查找的效率高,但是要將表按關鍵字排序。而排序本身是一
* 種很費時的運算。即使采用高效率的排序方法也要花費 O(n lg n)
* 的時間。
  二分查找只適用順序存儲結構。為保持表的有序性,在順序結構里插
入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建
立就很少改動、而又經常需要查找的線性表。
  對那些查找少而又經常需要改動的線性表,可采用鏈表作存儲結構,
進行順序查找。鏈表上無法實現二分查找

*/
import java.util.Arrays;

public class Search{
public void HalfSearch(int[] a, int b) {
  Arrays.sort(a);//系統排序
  int low = 0;
  int high = a.length - 1;
  int mid = (low + high) / 2;
  while ((mid != low) && (mid != high)) {
    if (b <= a[mid]) {
      high = mid;
    mid = (low + high) / 2;
  }

    else {
      low = mid;
      mid = (low + high) / 2;
}
}
    if ((b == a[low]) || (b == a[high])) {
      System.out.println(b + "在數組a中");
    }

     else {
      System.out.println(b + "不在數組a中");
}
}
public static void main(String[] args){
      Search s=new Search();
      int[] a={11,41,17,18,14,16,20,45};
      s.HalfSearch(a,20);
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM