QuickSort.h文件:
#include <iostream>
#include <string>
class QuickSort
{
public:
QuickSort();
~QuickSort();
void QuickSort::swap(int arr[], int i, int j);
void QuickSort::partitionQS(int arr[], int left, int right);
void QuickSort::quickSort(int arr[],int n);
private:
};
修改前,存在问题的QuickSort.cpp文件:
#include <iostream>
#include <string>
#include "QuickSort.h"
using namespace std;
QuickSort::QuickSort()
{
}
QuickSort::~QuickSort()
{
}
void QuickSort::swap(int arr[],int i,int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return;
}
void QuickSort::quickSort(int arr[],int n)
{
// 原子级逻辑 这种逻辑的结果是:最终左侧的数据都比中间小,右侧的数据都比中间大。 因此,可以通过二分法,递归调用。
/*
size_t i = 0;
size_t j = n;
for (; i < j && arr[i] > arr[0]; ++i);
for (; j > i && arr[j] < arr[0]; --j);
swap(arr, i, j);
if (arr[i]==arr[j] && arr[i]<arr[0])
{
swap(arr, 0, i);
} */
partitionQS(arr, 0, n-1);
return;
}
void QuickSort::partitionQS(int arr[],int left,int right)
{
rsize_t i = left;
rsize_t j = right;
if (left>=right)
{
return;
}
else
{
while (i<j)
{
for (; j > i && arr[j] > arr[left]; --j); //注意,以左侧为基数,需要右侧指针先扫描,最终才会相遇在小于基数的中间位置
for (++i; i < j && arr[i] < arr[left]; ++i);
swap(arr, i, j);
}
if (arr[i] == arr[j] )
{
if (arr[i]<arr[left])
{
swap(arr, left, i);
}
partitionQS(arr,left,i);
partitionQS(arr, i, right);
}
}
}
main.cpp文件:
#include <iostream>
#include <string>
#include "BubbleSort.h"
#include "SelectSort.h"
#include "InsertSort.h"
#include "QuickSort.h"
using namespace std;
void main(int arc, char ** argv)
{
const int ArSize = 20;
int arr[ArSize] = {6, 2, 8, 5, 1, 4 ,23,12,13,10,54,16,36,32,65,17,64,33,3,21};
//for (size_t i = 0; i < ArSize; i++)
//{
// cin >> arr[i];
//}
cout << "arr: ";
for (size_t i = 0; i < ArSize; i++)
{
cout << " " << arr[i];
}
cout << endl;
//BubbleSort bs;
//bs.bubbleSort(arr,ArSize);
//SelectSort ss;
//ss.selectSort(arr,ArSize);
//InsertSort is;
//is.insertSort(arr,ArSize);
QuickSort qs;
qs.quickSort(arr,ArSize);
cout << "sorted value: " << endl;
cout << "arr: ";
for (size_t i = 0; i < ArSize; i++)
{
cout << " " << arr[i] ;
}
cout << endl;
//cin.get();
cin.get();
return;
}
运行结果存在问题。
对代码进行修改 :
QuickSort.cpp 文件如下 :
#include <iostream>
#include <string>
#include "QuickSort.h"
using namespace std;
QuickSort::QuickSort()
{
}
QuickSort::~QuickSort()
{
}
void QuickSort::prtArr(int arr[], const int ArSize)
{
cout << "arr: ";
for (size_t i = 0; i < ArSize; i++)
{
cout << " " << arr[i];
}
cout << endl;
return;
}
void QuickSort::swap(int arr[],int i,int j)
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
return;
}
void QuickSort::quickSort(int arr[],int n)
{
// 原子级逻辑 这种逻辑的结果是:最终左侧的数据都比中间小,右侧的数据都比中间大。 因此,可以通过二分法,递归调用。
/*
size_t i = 0;
size_t j = n;
for (; i < j && arr[i] > arr[0]; ++i);
for (; j > i && arr[j] < arr[0]; --j);
swap(arr, i, j);
if (arr[i]==arr[j] && arr[i]<arr[0])
{
swap(arr, 0, i);
} */
quicksort(arr, 0, n-1);
return;
}
int QuickSort::partitionQS(int arr[],int left,int right)
{
int pivotPos = left;
int pivotKey = arr[left];
while (left<right)
{
for (; right > left && arr[right] >= pivotKey; --right); //注意,以左侧为基数,需要右侧指针先扫描,最终才会相遇在小于基数的中间位置
for (; left < right && arr[left] <= pivotKey; ++left);
if (left<right)
swap(arr, left, right);
}
swap(arr, pivotPos,left);
return left;
}
void QuickSort::quicksort(int arr[], int left, int right)
{
if (left >= right) // 边界条件
return;
prtArr(arr, 20);
int pivotPos = partitionQS(arr,left,right); // 单次划分
quicksort(arr, left, pivotPos-1); //左递归 调用
quicksort(arr, pivotPos+1, right); //右递归 调用
}
1、将单次的划分流程单独封装在一个函数里面, 功能是:输入两端值, 从两端向中间扫描,交换数值,直到指针相遇,交换基准值 并 输出中间值。
2、递归函数内部:
1)明确边界, left>=right
2)调用单次划分
3)递归
运行的过程及结果如下: