快速排序原理:
0 1 2 3 4 5 6 7
data 28 4 36 2 65 14 55 17
Piv i j
left right
left.right 排序范围
Pivot为每次范围内的最左边数, data[left]
i = left;
j = right+1;
1.从i+1位置往右寻找比Pivot大的数,得到索引i
2.从 j-1位置往左寻找比Pivot小的数,得到索引j
以上两个条件都严格边界,否则会产生无效运算
3.
如果i < j
则
data[i],data[j]交换
如果i < j,跳到第1步
4.
如果 i>= j 并且j != left
则
data[k],data[j]交换
到这步就产生了以Pivot为分界的两段数据,递归对两端数据进行1-4步运算
比如:
初始i = 0;j=8;
0 1 2 3 4 5 6 7 8
data 28 4 36 2 65 14 55 17
Piv i j
left right
第一趟
(1)
i = 2;
j = 7;
i < j,交换
0 1 2 3 4 5 6 7
data 28 4 17 2 65 14 55 36
Piv i j
left right
(2)
从i=3开始继续找>Pivot的数
0 1 2 3 4 5 6 7
data 28 4 17 2 65 14 55 36
Piv i j
left right
从 j=6开始继续找<Pivot的数
i = 4
j = 5
i< j,交换
0 1 2 3 4 5 6 7
data 28 4 17 2 14 65 55 36
Piv
left right
(3)
从i = 5, j = 4开始继续找
0 1 2 3 4 5 6 7
data 28 4 17 2 14 65 55 36
Piv j i
left right
i = 6
j = 4
i > j
把28换到j位置
0 1 2 3 4 5 6 7
data 14 4 17 2 28 65 55 36
Piv j i
left right
现在分成两段
[14 4 17 2] 28 [65 55 36]
递归下去,退出条件是left < right
- void Output(int array[], int n)
- {
- printf("%d:/t/t ", count++);
- for (int i=0; i<n; i++)
- {
- printf("%d ", array[i]);
- }
- printf("/n");
- }
- void swap(int &a, int &b)
- {
- printf("%d <- -> %d/n", a, b);
- int temp;
- temp = b;
- b = a;
- a = temp;
- }
- void QuickSort(int array[], int n, int left, int right)
- {
- int Pivot = array[left];
- int i = left;
- int j = right+1;
- if (left < right)
- {
- printf("new turn/n");
- while (i < j)
- {
- // 从+1位置找比Pivot大的
- do
- {
- i++;
- printf("i = %d/n", i);
- }while (array[i] <= Pivot && i < right);
- // 从最右边位置找比Pivot小的
- do
- {
- j--;
- printf("j = %d/n", j);
- }while (array[j] >= Pivot && j > left);
- // i < j,调整左右两边
- if (i < j)
- {
- swap(array[i], array[j]);
- Output(array, n);
- }
- }
- // i >=j 已经调整好,Pivot放置到中间值,如果j已经和left相等,那么不必再动位置了
- if (i >= j && j != left)
- {
- swap(array[left], array[j]);
- Output(array, n);
- }
- QuickSort(array, n, left, j-1);
- QuickSort(array, n, j+1, right);
- }
- }