快速排序基本思想:
对于partitioning的几点说明:
1. 把数组中最右边的元素作为partitioning element;
2. 从左向右扫描数组的元素,遇到 ">=partitioning element" 的情况就停止扫描;
3. 从右向左扫描数组的元素,遇到 "<=partitioning element" 的情况就停止扫描。
#include <iostream>
#include <time.h>
using namespace std;
void quicksort(int a[], int l, int r);
int partition(int a[], int l, int r);
void swap(int *a, int *b);
int main()
{
int n;
int *arr;
cin>>n;
arr = new int[n];
srand(unsigned(time(NULL)));
for (int i=0; i<n; i++)
{
// arr[i] = 10; // 测试所有值都相等的数组
// arr[i] = 15 - i; // 测试逆序数组
// arr[i] = i; // 测试正序数组
arr[i] = rand() % 100; // 测试随机数组
}
cout<<"Original Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
quicksort(arr, 0, n-1);
cout<<"Sorted Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void quicksort(int a[], int l, int r)
{
if (l >= r)
{
return ;
}
int pivot = partition(a, l, r);
quicksort(a, l, pivot-1);
quicksort(a, pivot+1, r);
}
int partition(int a[], int l, int r)
{
int i = l-1, j = r;
int v = a[r];
for ( ; ; )
{
// 注意:此处必须先++
// 特殊测试用例:所有元素都相等的数组
while (a[++i] < v)
{
}
// 注意:此处必须先--
while (v < a[--j])
{
if (j == l)
{
break;
}
}
if (i >= j)
{
break;
}
swap(&a[i], &a[j]);
}
// 注意:此处必须交换i位置上的元素和partitioning element,
// 不能交换j位置上的元素和partitioning element;
// 特殊测试用例:有序数组
swap(&a[i], &a[r]);
return i;
}
优化1:
// An iterative implementation of quick sort
#include <iostream>
#include <time.h>
using namespace std;
void swap(int *a, int *b);
int partition(int a[], int l, int r);
void quicksortIterative(int a[], int l, int r);
int main()
{
int n;
int *arr;
cin>>n;
arr = new int [n];
srand(unsigned(time(NULL)));
for (int i=0; i<n; i++)
{
arr[i] = rand() % 1000;
}
cout<<"Original Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
quicksortIterative(arr, 0, n-1);
cout<<"Sorted Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int a[], int l, int r)
{
int i = l - 1;
int j = r;
int v = a[r];
for ( ; ; )
{
while (a[++i] < v)
{
}
while (v < a[--j])
{
if (j == l)
{
break;
}
}
if (i >= j)
{
break;
}
swap(&a[i], &a[j]);
}
swap(&a[i], &a[r]);
return i;
}
void quicksortIterative (int arr[], int l, int r)
{
int *stack;
stack = new int [r-l+1];
int top = -1;
stack[ ++top ] = r;
stack[ ++top ] = l;
while ( top >= 0 )
{
l = stack[ top-- ];
r = stack[ top-- ];
if (r <= l)
{
continue;
}
int i = partition(arr, l, r);
// 保证左右两个子文件中较大的先入栈
// 这样可以减少栈的深度
if (i-1 > r-i)
{
stack[++top] = i-1;
stack[++top] = l;
stack[++top] = r;
stack[++top] = i+1;
}
else
{
stack[++top] = r;
stack[++top] = i+1;
stack[++top] = i-1;
stack[++top] = l;
}
}
}
Median-of-Three Partitioning
// An iterative implementation of quick sort
#include <iostream>
#include <time.h>
using namespace std;
void swap(int *a, int *b);
int partition(int a[], int l, int r);
void quicksortIterative(int a[], int l, int r);
int main()
{
int n;
int *arr;
cin>>n;
arr = new int [n];
srand(unsigned(time(NULL)));
for (int i=0; i<n; i++)
{
arr[i] = rand() % 1000;
}
cout<<"Original Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
quicksortIterative(arr, 0, n-1);
cout<<"Sorted Sequence"<<endl;
for (int i=0; i<n; i++)
{
cout<<arr[i]<<" ";
}
cout<<endl;
system("pause");
return 0;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int a[], int l, int r)
{
int i = l - 1;
int j = r;
int v = a[r];
for ( ; ; )
{
while (a[++i] < v)
{
}
while (v < a[--j])
{
if (j == l)
{
break;
}
}
if (i >= j)
{
break;
}
swap(&a[i], &a[j]);
}
swap(&a[i], &a[r]);
return i;
}
void quicksortIterative (int arr[], int l, int r)
{
int *stack;
stack = new int [r-l+1];
int top = -1;
stack[ ++top ] = r;
stack[ ++top ] = l;
while ( top >= 0 )
{
l = stack[ top-- ];
r = stack[ top-- ];
if (r <= l)
{
continue;
}
int i = partition(arr, l, r);
// 保证左右两个子文件中较大的先入栈
// 这样可以减少栈的深度
if (i-1 > r-i)
{
stack[++top] = i-1;
stack[++top] = l;
stack[++top] = r;
stack[++top] = i+1;
}
else
{
stack[++top] = r;
stack[++top] = i+1;
stack[++top] = i-1;
stack[++top] = l;
}
}
}