PartitionOne是一种常规的划分方法,使用low和high指针从数组的两端进行处理。
PartitionTwo是从low到high的方向进行处理,当数组部分有序时,[0-j]表示小于sentinel的元素,[j+1,i]表示大于sentinel的元素,当某个待处理的数小于sentinel时(下标为i+1),就将数组中j+1与i+1位置上的数互换,那么此时[0-j+1]就表示小于sentinel的元素,[j+2,i+1]表示大于sentinel的元素,[0,i+1]的数组都是有序的,直到最后处理完所有数据
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
int PartitionOne(int *arr, int low, int high)
{
int sentinel = arr[low];
while (low < high)
{
while (low < high && arr[high] >= sentinel)
{
--high;
}
arr[low] = arr[high];
while (low < high && arr[low] <= sentinel)
{
++low;
}
arr[high] = arr[low];
}
arr[low] = sentinel;
return low;
}
int PartitionTwo(int *arr, int low, int high)
{
int sentinel = arr[high];
int j = low - 1; //j指向部分排序后数组中小于sentinel的最后一个节点
for (int i = low; i < high; i++)
{
if (arr[i] <= sentinel)
{
j++;
swap(&arr[i], &arr[j]);
}
}
swap(&arr[j + 1], &arr[high]);
return (j + 1);
}
int RandomPartition(int *arr, int low, int high)
{
int randomNum = (int)((rand() % (high - low)) + low);
swap(&arr[randomNum], &arr[high]);
return PartitionTwo(arr, low, high);
}
void QuickSort(int *arr, int low, int high)
{
if (low < high)
{
int partition = RandomPartition(arr, low, high);
QuickSort(arr, low, partition - 1);
QuickSort(arr, partition + 1, high);
}
}
int main()
{
int arr[20];
int i;
srand((unsigned)time(NULL));
for (i = 0; i < 20; ++i)
arr[i] = (int)(rand() % 19 + 1);
for (i = 0; i < 20; ++i)
printf("%d ", arr[i]);
printf("\n");
QuickSort(arr, 0, 19);
for (i = 0; i < 20; ++i)
printf("%d ", arr[i]);
printf("\n");
return 0;
}