快速排序(一)

/**
* <p>Title:快速排序 </p>
* <p>Description:
 * 速排序法(quick sort)是目前所公認最快的排序方法之一(視解題的對象而定),
 * 雖然快速排序法在最差狀況下可以達O(n2),但是在多數的情況下,快速排序法的效率表現是相當不錯的。
 * 快速排序法的基本精神是在數列中找出適當的軸心,然後將數列一分為二,分別對左邊與右邊數列進行排序,而影響快速排序法效率的正是軸心的選擇。
 * </p>
* <p>Copyright: Copyright (c) 2006</p>
* <p>Company: </p>
* @author not attributable
* @version 1.0
*/
public class QuickSort {

  public static void print(int[] number) {//打印输入数组内容
    for (int i = 0; i < number.length; i++) {
      System.out.print(number[i] + ",");
    }
    System.out.println("");
  }

  public static void swap(int[] number, int i, int j) {//交换number数组索引i,j处的值
    int tmp;
    tmp = number[i];
    number[i] = number[j];
    number[j] = tmp;
  }
  /**
   * 以左边元素为轴的快速排序
   * 解法:
   * 1.將最左邊的數設定為軸,並記錄其值為 s
   * 廻圈處理:
   * 2.令索引 i 從數列左方往右方找,直到找到大於 s 的數
   * 3.令索引 j 從數列右方往左方找,直到找到小於 s 的數
   * 4.如果 i >= j,則離開迴圈
   * 5.如果 i < j,則交換索引i與j兩處的值
   * 6.將左側的軸與 j 進行交換
   * 7.對軸左邊進行遞迴
   * 8.對軸右邊進行遞迴
   * 透過以下演算法,則軸左邊的值都會小於s,軸右邊的值都會大於s,如此再對軸左右兩邊進行遞迴,就可以對完成排序的目的
   * 例如下面的實例,*表示要交換的數,[]表示軸:
   * [41] 24 76* 11 45 64 21 69 19 36*
   * [41] 24 36 11 45* 64 21 69 19* 76
   * [41] 24 36 11 19 64* 21* 69 45 76
   * [41] 24 36 11 19 21 64 69 45 76
   * 21 24 36 11 19 [41] 64 69 45 76
   * 在上面的例子中,41左邊的值都比它小,而右邊的值都比它大,如此左右再進行遞迴至排序完成。
   *
   * @param number 排序数组
   * @param left  开始索引
   * @param right 结束索引
   */
  public static void sort(int[] number, int left, int right) {
    if (left < right) {
      int s = number[left];
      int i = left;
      int j = right + 1;
      int len = number.length;
      while (true) {
        while (i+1<len && number[++i] < s)// 向右找
          ;
        while (j-1>-1 && number[--j] > s)    // 向左找
          ;
        if (i >= j)
          break;
        swap(number, i, j);
        print(number);
      }
      number[left] = number[j];
      number[j] = s;
      sort(number, left, j - 1); // 對左邊進行遞迴
      sort(number, j + 1, right); // 對右邊進行遞迴
    }
  }
  /**
   * 以中间元素为轴的快速排序
   * 取中間的元素s作比較,同樣的先得右找比s大的索引 i,然後找比s小的索引 j,
   * 只要兩邊的索引還沒有交會,就交換 i 與 j 的元素值,這次不用再進行軸的交換了,因為在尋找交換的過程中
   * ,軸位置的元素也會參與交換的動作,例如:
   * 41 24 76 11 45 64 21 69 19 36
   * 首先left為0,right為9,(left+right)/2 = 4(取整數的商),所以軸為索引4的位置,
   * 比較的元素是45,您往右找比45大的,往左找比45小的進行交換:
   * 41 24 76* 11 [45] 64 21 69 19 *36
   * 41 24 36 11 45* 64 21 69 19* 76
   * 41 24 36 11 19 64* 21* 69 45 76
   * [41 24 36 11 19 21] [64 69 45 76]
   * 完成以上之後,再初別對左邊括號與右邊括號的部份進行遞迴,如此就可以完成排序的目的。
   * @param number
   * @param left
   * @param right
   */
  public static void sort1(int[] number, int left, int right) {
    if(left < right){
      int i = left -1 ;
      int j = right+1;
      int mid  = (left+right)>>>1;
      int s = number[mid];
      int len = number.length;
      while(true){
        while(i+1<len && number[++i] < s)//向右移
          ;
        while(j-1>-1 && number[--j] > s)//向左移
          ;
        if(i>j)
          break;
        swap(number,i,j);
        print(number);
      }
      sort1(number,left,j);
      sort1(number,i,right);
    }
  }
  public static void sort2(int[] number, int left, int right) {

  }
  public static void main(String[] args) {
    int[] number = {
        -6,-1};
    sort1(number, 0, number.length - 1);
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值