版权声明:copyright@xxdk2017 https://blog.csdn.net/u011583798/article/details/78143920
快速排序本质是一种切分交换比较思想:
对数组N array[10] = {88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
选array[0]为参考对象,选两个索引i,j,i指向数组第二个array[1],
j指向数组末尾array[9];
向右滑动 i, 如果array[i] > 88 && i <= 9, 则暂停i滑动
改为向左滑动j, 如果array[j] < 88 && j >= 0, 并且j>i
则交换array[i] 与 array[j];
<i = 1 j = 9>{88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
<i = 7 j = 9>{88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
交换array[7] 与 array[9]得到
<i = 7 j = 9>{88, 22, 66, 77, 55, 44, 33, 0, 11, 99};
将j前移一个位置, i后移一个位置
<i = 8 j = 8>{88, 22, 66, 77, 55, 44, 33, 0, 11, 99};
i,j 相遇将参考对象array[0] 与 array[j] 交换
<i = 8 j = 8>{11, 22, 66, 77, 55, 44, 33, 0, 88, 99};
如此,一次切分完成,此时参考元素88左边的元素均不大于88, 右边均不小于88.也就是88已经是排序完成的最终位置了.然后,对参考元素切分成的左右两边两个子数组,继续进行切分交换,只到子数组长度为1,此时整个数组排序完成.
-----------------------------------------------------------------------
----左{11, 22, 66, 77, 55, 44, 33, 0}右{99}
参考元素 11 <i = 1, j = 7> {11, 22, 66, 77, 55, 44, 33, 0};
左右交换 11 <i = 1, j = 7> {11, 0, 66, 77, 55, 44, 33, 22};
i++, j-- 11 <i = 2, j = 6> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 5> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 4> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 3> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 2> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 1> {11, 0, 66, 77, 55, 44, 33, 22};
参考交换 {0, 11, 66, 77, 55, 44, 33, 22};
-----------------------------------------------------------------------
----左{0}, 右{66, 77, 55, 44, 33, 22};
参考元素 66 <i = 1, j = 5> {66, 77, 55, 44, 33, 22};
左右交换 66 <i = 1, j = 5> {66, 22, 55, 44, 33, 77};
i++, j-- 66 <i = 2, j = 4> {66, 22, 55, 44, 33, 77};
i++, j 66 <i = 3, j = 4> {66, 22, 55, 44, 33, 77};
i++, j 66 <i = 4, j = 4> {66, 22, 55, 44, 33, 77};
参考交换 {33, 22, 55, 44, 66, 77}
-----------------------------------------------------------------------
----左{33, 22, 55, 44}, 右{77}
参考元素 33 <i = 1, j = 3> {33, 22, 55, 44}
参考交换 {22, 33, 55, 44}
-----------------------------------------------------------------------
----左{22} 右{55, 44}
参考元素 55 <i = 1, j = 1} {55, 44}
参考交换 {44, 55}
-----------------------------------------------------------------------
左{44}, 右x
-----------------------排序完成------------------------------------
将之前所得所有的一元数组和参考因素垂直投影得到有序数组
对数组N array[10] = {88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
选array[0]为参考对象,选两个索引i,j,i指向数组第二个array[1],
j指向数组末尾array[9];
向右滑动 i, 如果array[i] > 88 && i <= 9, 则暂停i滑动
改为向左滑动j, 如果array[j] < 88 && j >= 0, 并且j>i
则交换array[i] 与 array[j];
<i = 1 j = 9>{88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
<i = 7 j = 9>{88, 22, 66, 77, 55, 44, 33, 99, 11, 0};
交换array[7] 与 array[9]得到
<i = 7 j = 9>{88, 22, 66, 77, 55, 44, 33, 0, 11, 99};
将j前移一个位置, i后移一个位置
<i = 8 j = 8>{88, 22, 66, 77, 55, 44, 33, 0, 11, 99};
i,j 相遇将参考对象array[0] 与 array[j] 交换
<i = 8 j = 8>{11, 22, 66, 77, 55, 44, 33, 0, 88, 99};
如此,一次切分完成,此时参考元素88左边的元素均不大于88, 右边均不小于88.也就是88已经是排序完成的最终位置了.然后,对参考元素切分成的左右两边两个子数组,继续进行切分交换,只到子数组长度为1,此时整个数组排序完成.
-----------------------------------------------------------------------
----左{11, 22, 66, 77, 55, 44, 33, 0}右{99}
参考元素 11 <i = 1, j = 7> {11, 22, 66, 77, 55, 44, 33, 0};
左右交换 11 <i = 1, j = 7> {11, 0, 66, 77, 55, 44, 33, 22};
i++, j-- 11 <i = 2, j = 6> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 5> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 4> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 3> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 2> {11, 0, 66, 77, 55, 44, 33, 22};
i, j-- 11 <i = 2, j = 1> {11, 0, 66, 77, 55, 44, 33, 22};
参考交换 {0, 11, 66, 77, 55, 44, 33, 22};
-----------------------------------------------------------------------
----左{0}, 右{66, 77, 55, 44, 33, 22};
参考元素 66 <i = 1, j = 5> {66, 77, 55, 44, 33, 22};
左右交换 66 <i = 1, j = 5> {66, 22, 55, 44, 33, 77};
i++, j-- 66 <i = 2, j = 4> {66, 22, 55, 44, 33, 77};
i++, j 66 <i = 3, j = 4> {66, 22, 55, 44, 33, 77};
i++, j 66 <i = 4, j = 4> {66, 22, 55, 44, 33, 77};
参考交换 {33, 22, 55, 44, 66, 77}
-----------------------------------------------------------------------
----左{33, 22, 55, 44}, 右{77}
参考元素 33 <i = 1, j = 3> {33, 22, 55, 44}
i, j-- 33 <i = 1, j = 2> {33, 22, 55, 44}
i, j-- 33 <i = 1, j = 1> {33, 22, 55, 44}
-----------------------------------------------------------------------
----左{22} 右{55, 44}
参考元素 55 <i = 1, j = 1} {55, 44}
参考交换 {44, 55}
-----------------------------------------------------------------------
左{44}, 右x
-----------------------排序完成------------------------------------
将之前所得所有的一元数组和参考因素垂直投影得到有序数组
示例:
/*************************************************************************
> File Name: quick_sort.h
> Author: XXDK
> Email: [email protected]
> Created Time: Sat 30 Sep 2017 11:06:40 AM CST
************************************************************************/
#ifndef _QUICK_SORT_H
#define _QUICK_SORT_H
#include <iostream>
#include <vector>
template <typename T>
class QuickSort
{
private:
int lo;
int hi;
std::vector<T> array;
public:
QuickSort(std::vector<T>& _array)
{
lo = 0; // first element array[lo]
hi = _array.size() - 1; // last element array[hi]
for(int i = 0; i < _array.size(); i++) {
array.push_back(_array[i]);
}
}
void printArray(void)
{
for (int i = 0; i < array.size(); i++)
std::cout << ' ' << array[i];
std::cout << '\n';
}
void quick_sort(void) {
quickSort(array, lo, hi);
}
private:
int xless(const T& obj1, const T& obj2)
{
return obj1 < obj2 ? 1 : 0;
}
void exchange(std::vector<T>& _array, int idx1, int idx2)
{
//std::cout << "exchange array[" << idx1 << "]"<< "( " << array[idx1] << " ) " << "with array[" << idx2 << "]" <<"( " << array[idx2] << " )"<< std::endl;
T temp = _array[idx1];
_array[idx1] = _array[idx2];
_array[idx2] = temp;
}
int partition(std::vector<T>& _array, int _lo, int _hi)
{
int i = _lo, j = _hi+1; // left and right scan indices
T pelm = _array[_lo]; // partition element
while (true) {
// scan right, scan left, check for scan complete, and exchange
while (xless(_array[++i], pelm)) { // slide to where a[i] > pelm
if (i == _hi)
break;
}
while (xless(pelm, _array[--j])) { // slide to where a[j] < pelm
if (j == _lo)
break;
}
if (i >= j)
break;
exchange(_array, i, j); // exchange a[i] and a[j]
std::cout << "i = " << i << ", j = " << j;
printArray();
}
//std::cout << "partition element to final position: array["<< j << "]" << std::endl;
exchange(_array, _lo, j); // put partition element to final position j
std::cout << "i = " << i << ", j = " << j;
printArray();
return j;
}
void quickSort(std::vector<T>& _array, int _lo, int _hi)
{
int p;
if(_lo >= _hi)
return;
//std::cout <<"quick sort lo = " << _lo << ", hi = " << _hi <<std::endl;
p = partition(_array, _lo, _hi);
quickSort(_array, _lo, p-1);
quickSort(_array, p+1, _hi);
}
};
#endif // _QUICK_SORT_H
/*************************************************************************
> File Name: quick_sort.cpp
> Author: XXDK
> Email: [email protected]
> Created Time: Sat 30 Sep 2017 09:17:36 AM CST
************************************************************************/
#include"quick_sort.h"
int main()
{
int testData[] = {88, 44, 11, 55, 99, 22, 77, 33, 0, 66};
std::vector<int> array(testData, testData + sizeof(testData)/sizeof(testData[0]));
QuickSort<int> qs(array);
std::cout << " ";
qs.printArray();
qs.quick_sort();
std::cout << " ";
qs.printArray();
}