快速排序

陣列2,5,3,6,4,1

值將陣列0的資料作為基準

以下圖來說,陣列0的值是2,是作為比較大小的標準。

L指向陣列0的位址

R指向陣列最後的位址

img

比較R值,尋找比基準值小

預設先比對R的值

若陣列[R]<2,將陣列[L]的值設成陣列[R],並且L前進一格。

若以上條件不符合,R往後退一格。

if(陣列[R] < 2) {
	陣列[L] = 陣列[R]
	L++;
} else {
	R--;
}

下圖陣列[R]<2,將陣列[L]的值設成陣列[R],並且L前進一格

img

比較L值,尋找比基準值大

若陣列[L]>2,將陣列[R]的值設成陣列[L],並且R往後退一格。

若以上條件不符合,L往前一格。

if(陣列[L] > 2) {
	陣列[R] = 陣列[L]
	R--;
} else {
	L++;
}

下圖陣列[L]>2,將陣列[R]的值設成陣列[L],並且R後退一格

img

L==R

若陣列[R]一直找不到比2小,就會一直往後退移到跟L相同的位址。

將基準值2放入L==R的位址,第一個數字排序好

img

遞迴設定

下圖中從2(已排序好)作為中點,分為左右二半,左邊剩下1個,右邊剩下4個待排序。

左邊只剩下1個,至少要有2個數字才可以比較大小,因此視作排序完成。

把arr指標移動2格(arr+2),從3的數字開始視作為陣列起點,大小為4個。

left的陣列位址為1,len(陣列長度)為6

quickSort(arr + left + 1, len - left - 1);

以上程式轉換如下

quickSort(arr + 2, 4);

img

重新設定L、R與基準值

將L指向數字3,並將比較基準值設為3,R指向陣列最尾部。

img

R找不到比基準值小的值

R指標找不到比基準值3小的,最後L==R

img

L==R(2)

將基準值3放入L==R的位址,第二個數字排序好

img

重新設定L、R與基準值(2)

將L指向數字6,並將基準值設為6,R指向陣列最尾部。

img

比較R值,尋找比基準值小(2)

預設先比對R的值

若陣列[R]<6,將陣列[L]的值設成陣列[R],並且L前進一格。

img

L==R(3)

將基準值6放入L==R的位址,第三個數字排序好

img

重新設定L、R與基準值(3)

img

比較R值,尋找比基準值小(3)

預設先比對R的值

若陣列[R]<5,將陣列[L]的值設成陣列[R],並且L前進一格。

img

L==R(4)

將基準值5放入L==R的位址,第四個數字排序好

img

重點步驟

  • 至少要有2個數字才可以比較大小
  • L指向陣列0的位址
  • R指向陣列最後的位址
  • 將陣列0的值作為基準值
  • 預設先比較R值
  • L<R,比較R值,尋找比基準值小
  • L<R,比較L值,尋找比基準值大
  • L==R,將基準值放入L==R的位址
  • 基準值作為中點,陣列分為左右二半(不包含基準值的位址)
  • 左右二半陣列繼續依上述文字進行,直至陣列個數小於2

完整程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
 參數1 陣列位址
 參數2 陣列大小
 */
void quickSort(int arr[], int len) {
  //至少要有2個數字才可以比較大小
  if(len < 2) return;
  int left = 0;
  int right = len - 1;
  //基準值都為arr[0]
  int pivot = arr[0];
  //預設先比較R
  //action有L與R,預設先比對R的值
  char action = 'R';
  //若left<right才進入循環
  while(left < right) {
    //比較R值,尋找比基準值小
    if(action == 'R') {
      //比較R值,尋找比基準值小
      //若陣列[R]<基準值,將陣列[L]的值設成陣列[R],並且L前進一格。
      if(arr[right] < pivot) {
        arr[left] = arr[right];
        left++;
        //設定下一次是L移動
        action = 'L';
      } else {
        //若以上條件不符合,R往後退一格。
        right--;
      }
    //比較L值,尋找比基準值大
    } else if(action == 'L') {
      //比較L值,尋找比基準值大
      //若陣列[L]>基準值,將陣列[R]的值設成陣列[L],並且R往後退一格。
      if(arr[left] > pivot) {
        arr[right] = arr[left];
        right--;
        //設定下一次是R移動
        action = 'R';
      } else {
        //若以上條件不符合,L往前一格。
        left++;
      }
    }
  }
  //L==R
  //將基準值放入L==R的位址
  arr[right] = pivot;
  //遞迴設定
  //基準值作為中點,分為左右二半陣列(不包含基準值)
  //參數1陣列起始位址,參數2分成左右二半的各別個數
  //左半邊
  quickSort(arr,left);
  //右半邊
  //起始位址在基準值位址的下一格
  //個數(請參照遞迴設定的說明與圖)
  quickSort(arr + left + 1, len - left - 1);
}
int main() {
  int arr[] = {6,5,4,3,2,1};
  int len = sizeof(arr)/sizeof(int);
  quickSort(arr, len);
  for(int i = 0; i < len; i++) {
    cout << arr[i] << ",";
  }
  cout << endl;
  return 0;
}

results matching ""

    No results matching ""