快排的理论部分,有兴趣者可点击博客 温故而知新 -> 数据结构 ->排序 或通过其他方式进行理解!
博主其实之前实现过快排,具体可见博客 温故而知新 -> 数据结构 ->排序 ->程序实现2_利用C++ 中的内容,但因为当时实现是函数之间的层层调用,虽然理解不难,但代码量会比较多,也有点麻烦,所以在本篇博客中将对其进行精简!
快排中,将区间按照基准值划分为左右两半部分的常见方式有:
所以下面的程序实现将按这三种方法进行说明!
#include
#include
using namespace std;
void display(vector<int>& arr)
{
for (auto& n : arr)
cout << n << " ";
cout << endl;
}
// 将数组以升序进行排列!
void quickSort(vector<int>& arr, int left, int right) // hoare 升序
{
if (left >= right)
return;
int key = arr[left];
int begin = left;
int end = right;
int start = left;
while (begin < end)
{
while (begin < end && arr[end] >= key)
--end;
while (begin < end && arr[begin] <= key)
++begin;
if (begin != end)//此句是用于减少不必要的操作,可加可不加
swap(arr[begin], arr[end]);
}
swap(arr[start], arr[begin]);
quickSort(arr, left, begin - 1);//此处begin与end可任选其一
quickSort(arr, begin + 1, right);
}
// 将数组以降序进行排列!
void quickSort_2(vector<int>& arr, int left, int right) // hoare 降序
{
if (left >= right)
return;
int key = arr[left];
int begin = left;
int end = right;
int start = left;
while (begin < end)
{
while (begin < end && arr[end] <= key)
--end;
while (begin < end && arr[begin] >= key)
++begin;
if (begin != end)//此句可加可不加
swap(arr[begin], arr[end]);
}
swap(arr[start], arr[begin]);
quickSort_2(arr, left, begin - 1);//此处begin与end可任选其一,因为上面的循环结束后,begin会与end相等
quickSort_2(arr, begin + 1, right);
}
void test()
{
vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
cout << "原数组:"; display(arr);
quickSort(arr, 0, arr.size() - 1);
cout << "升序排列:"; display(arr);
quickSort_2(arr, 0, arr.size() - 1);
cout << "降序排列:"; display(arr);
}
int main()
{
test();
return 0;
}
注意:上述升序与降序的主要区别就是程序中的大小判断条件相反!
#include
#include
using namespace std;
void display(vector<int>& arr)
{
for (auto& n : arr)
cout << n << " ";
cout << endl;
}
// 将数组以升序进行排列!
void quickSort2(vector<int>& arr, int left, int right)
{
if (left >= right)
return;
int key = arr[left];
int begin = left;
int end = right;
while (begin < end)
{
while (begin < end && arr[end] >= key)
--end;
arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
while (begin < end && arr[begin] <= key)
++begin;
arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
}
arr[begin] = key;
quickSort2(arr, left, end - 1);
quickSort2(arr, end + 1, right);
}
// 将数组以降序进行排列!
void quickSort2_2(vector<int>& arr, int left, int right)
{
if (left >= right)
return;
int key = arr[left];
int begin = left;
int end = right;
while (begin < end)
{
while (begin < end && arr[end] <= key)
--end;
arr[begin] = arr[end];//此处其实也可通过判断begin与end是否相等来减少多余操作
while (begin < end && arr[begin] >= key)
++begin;
arr[end] = arr[begin];//此处其实也可通过判断begin与end是否相等来减少多余操作
}
arr[begin] = key;
quickSort2_2(arr, left, begin - 1);
quickSort2_2(arr, begin + 1, right);
}
void test()
{
vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
cout << "原数组:"; display(arr);
quickSort2(arr, 0, arr.size() - 1);
cout << "升序排列:"; display(arr);
quickSort2_2(arr, 0, arr.size() - 1);
cout << "降序排列:"; display(arr);
}
int main()
{
test();
return 0;
}
#include
#include
using namespace std;
void display(vector<int>& arr)
{
for (auto& n : arr)
cout << n << " ";
cout << endl;
}
// 将数组以升序进行排列!
void quickSort3(vector<int>& arr, int left, int right)
{
if (left >= right)
return;
int prev = left;
int cur = left + 1;
int key = arr[left];
while (cur <= right)
{
if (arr[cur] < key && ++prev != cur)//小于基准值且不连续时进行交换
swap(arr[prev], arr[cur]);
++cur;
}
swap(arr[left], arr[prev]);
quickSort3(arr, left, prev - 1);
quickSort3(arr, prev + 1, right);
}
// 将数组以降序进行排列!
void quickSort3_2(vector<int>& arr, int left, int right)
{
if (left >= right)
return;
int prev = left;
int cur = left + 1;
int key = arr[left];
while (cur <= right)
{
if (arr[cur] > key && ++prev != cur)//小于基准值且不连续时进行交换
swap(arr[prev], arr[cur]);
++cur;
}
swap(arr[left], arr[prev]);
quickSort3_2(arr, left, prev - 1);
quickSort3_2(arr, prev + 1, right);
}
void test()
{
vector<int> arr = { 6, 3, 1, 8, 7, 2, 4 };
cout << "原数组:"; display(arr);
quickSort3(arr, 0, arr.size() - 1);
cout << "升序排列:"; display(arr);
quickSort3_2(arr, 0, arr.size() - 1);
cout << "降序排列:"; display(arr);
}
int main()
{
test();
return 0;
}
上述三种方法,个人推荐用第二种~