单向划分,快速排序(C++)
快速排序
前言
常见的快速排序有两个指针分别指向数组的两头,这两个指针双向地对数组进行遍历。今天我学习了另一种快速排序的方法,叫做单向划分函数快速排序。
单向划分函数
顾名思义,只需要一个从左到右的方向来遍历数组,如何实现呢?
需要定义两个指针,一个指向分段数组的最左边元素(称之为i),另一个指针指向最左边-1(称之为j),将指定的值存为一个变量(tmp)。
之后遍历这个数组,如果i指向的元素小于或等于tmp,则让j+1,将i与j指向的元素交换,直到i指向数组最后一个元素。
这么做的目的可以保证j指针所指向的值永远小于指定的值(tmp)。
最后将tmp与j指向的元素交换即可。
举例
初始化:将数组的第一个元素赋值给tmp
第一步:因为56==56,所以j+1并与i交换,i+1
第二步:因为23<56,所以j+1并与i交换,i+1
第三步:因为78>56,所以j不动,i+1
第四步:因为45<56,所以j+1并与i交换,i+1
由此不难看出,j所指向的元素永远小于指定元素。
代码
快速排序函数
利用RandomPatition函数返回一个中间值,利用中间值将数组划分为两个部分
void QuickSort(int* nums, int left, int right)
{
if (left > right) return;
int mid = RandomPatition(nums, left, right);
QuickSort(nums, left, mid - 1);
QuickSort(nums, mid + 1, right);
}
随机指定值
利用rand函数指定数组中任意一个位置的数,将它与数组第一个元素交换
int RandomPatition(int* nums, int left, int right)
{
srand(time(nullptr));
int rapos = rand() % (right - left + 1) + left;
swap(nums[left], nums[rapos]);
return Patiton(nums, left, right);
}
划分函数
将小于指定值的元素置于左边,将大于指定值的元素置于右边。最后返回中间值位置。
int Patiton(int* nums, int left, int right)
{
int i = left;
int j = left - 1;
int tmp = nums[left];
while (i <= right)
{
if (nums[i] <= tmp)
{
j++;
swap(nums[i], nums[j]);
}
i++;
}
swap(nums[j], nums[left]);
return j;
}
全部代码
#include<iostream>
using namespace std;
int Patiton(int* nums, int left, int right)
{
int i = left;
int j = left - 1;
int tmp = nums[left];
while (i <= right)
{
if (nums[i] <= tmp)
{
j++;
swap(nums[i], nums[j]);
}
i++;
}
swap(nums[j], nums[left]);
return j;
}
int RandomPatition(int* nums, int left, int right)
{
srand(time(nullptr));
int rapos = rand() % (right - left + 1) + left;
swap(nums[left], nums[rapos]);
return Patiton(nums, left, right);
}
void QuickSort(int* nums, int left, int right)
{
if (left > right) return;
int mid = RandomPatition(nums, left, right);
QuickSort(nums, left, mid - 1);
QuickSort(nums, mid + 1, right);
}
void show(int* nums, int n)
{
for (int i = 0; i < n; i++)
{
cout << nums[i] << " ";
}
cout << endl;
}
int main()
{
int nums[] = { 56,23,78,45,90,89,12,34,56,67,89,100 };
int n = sizeof(nums) / sizeof(nums[0]);
show(nums, n);
QuickSort(nums, 0, n - 1);
show(nums, n);
return 0;
}