class Solution {
public:
/*
* @param A: an integer array
* @return:
*/
void sortIntegers2(vector<int> &A) {
// write your code here
quickSort(A, 0, A.size() - 1);
//quickSort2(A, 0, A.size() - 1);
//HoareQuickSort(A, 0, A.size() - 1);
//LomutoQuickSort(A, 0, A.size() - 1);
//Median3QuickSort(A, 0, A.size() - 1);
//mergeSort(A);
//Heapsort(A);
}
private:
/*================== Quick Sort====================*/
void quickSort(vector<int> &A, int l, int r) {
if (l >= r) { // 注意判断条件,l<j才执行
return;
}
int i = l, j = r;
int pivot = A[(l + r) / 2];
while (i <= j) {
while (i <= j && A[i] < pivot) {
i++;
}
while (i <= j && A[j] > pivot) {
j--;
}
if (i <= j) { // 必定会交换
swap(A[i], A[j]);
i++;
j--;
}
}
// pivot有可能落入前半段或者后半段,所以分开两段再递归,还是比不上Hoare分割
quickSort(A, i, r);
quickSort(A, l, j);
}
/*================ */
// 选择中值为中轴,来进行分裂
int partition2(vector<int> &a, int left, int right) {
if (left<0 || right<=0 || left>=right)
return -1;
int p = a[(left + right) / 2]; // Pivot
int i = left;
int j = right;
while (i <= j) {
// find the date at left side shift to right side
while (i<=j && a[i]<p)
i++;
// find the data at right side shift to left side
while (i<=j && a[j]>p)
j--;
// swap
if (i <= j) { // 一定会交换
swap(a[i], a[j]);
i++;
j--;
}
}
// pivot有可能在前半段有可能在后半段
return i;
}
void quickSort2(vector<int> &a, int left, int right) {
if (left < right) {
int index = partition2(a, left, right); // 获取分裂位置
// pivot有可能在前半段有可能在后半段, 再分开两段来递归
if (left < index-1)
quickSort2(a, left, index-1);
if (index < right)
quickSort2(a, index, right);
}
}
/*=======================HoareQuickSort==============================*/
void HoareQuickSort(vector<int> &A, int l, int r) {
if (l < r) {
int s = HoarePartition(A, l, r); //s是分裂位置
HoareQuickSort(A, l, s-1);
HoareQuickSort(A, s+1, r);
}
}
// 第一个元素作为中轴,进行划分
int HoarePartition(vector<int> &A, int l, int r) {
int p = A[l];//dealPivot(A, l, r);//RandomInRange(A, l, r);
int i = l;
int j = r+1;
do {
do {
i++;
} while (A[i] < p);
do {
j--;
} while (A[j] > p);
swap(A[i], A[j]);
} while (i < j);
swap(A[i], A[j]); //当i>=j撤销最后一次交换
swap(A[l], A[j]);
return j;
}
/*=======================LomutoQuickSort==============================*/
void LomutoQuickSort(vector<int> &A, int l, int r) {
if (l < r) {
int s = LomutoPartition(A, l, r); //s是分裂位置
LomutoQuickSort(A, l, s-1);
LomutoQuickSort(A, s+1, r);
}
}
// 第一个元素作为中轴,进行划分,从左到右进行单项扫描划分
int LomutoPartition(vector<int> &A, int l, int r) {
int p = A[l];
int s = l;
for (int i=l+1; i<=r; i++) {
if (A[i] < p) {
s++; // 先增加s的右边
swap(A[s], A[i]);// 交换到最右边的s位置
}
}
swap(A[l], A[s]);
return s;
}
/*=======================median of three method===========================*/
void Median3QuickSort(vector<int> &A, int l, int r) {
if (l < r) {
int s = HoarePartition(A, l, r); //s是分裂位置
Median3QuickSort(A, l, s-1);
Median3QuickSort(A, s+1, r);
}
}
// 第一个元素作为中轴,进行划分
int dealPivot(vector<int> &A, int l, int r) {
int mid = (l + r) / 2;
if (A[l] > A[mid]) {
swap(A[l], A[mid]);
}
if (A[l] > A[r]) {
swap(A[l], A[r]);
}
if (A[r] < A[mid]) {
swap(A[r], A[mid]);
}
// 放到最左边
swap(A[l], A[mid]);
return A[l];
}
// l和r中间的随机数作为中轴
int RandomInRange(vector<int> &A, int l,int r) {
srand ( time(NULL) );
int num = rand() % (r-l+1) + l;
// 放到最左边
swap(A[l], A[num]);
return A[l];
}
/*==================Random QuickSort method===========================*/
// 从l, r到范围内随机数选择一个位置,此位置和l位置交换,接着用HoareQuickSort
// 排序即可
/*===================== Merge Sort=======================*/
// Lpos = start of left half, Rpos = start of right half
void merge(vector<int> &a, vector<int> &tmpArray, int Lpos, int Rpos, int RightEnd) {
int LeftEnd = Rpos - 1;
int NumElement = RightEnd - Lpos + 1; // Based on the index
int TmpPos = Lpos;
while (Lpos<=LeftEnd && Rpos<=RightEnd) {
if (a[Lpos]<=a[Rpos])
tmpArray[TmpPos++] = a[Lpos++];
else
tmpArray[TmpPos++] = a[Rpos++];
}
while (Lpos<=LeftEnd)
tmpArray[TmpPos++] = a[Lpos++];
while (Rpos<=RightEnd)
tmpArray[TmpPos++] = a[Rpos++];
// copy tmpArray back
for (int i=0; i<NumElement; i++, RightEnd--)
a[RightEnd] = tmpArray[RightEnd];
}
void mergeSort(vector<int> &a, vector<int> &tmpArray, int Left, int Right) {
if (Left < Right) {
int mid = (Left + Right) / 2;
mergeSort(a, tmpArray, Left, mid);
mergeSort(a, tmpArray, mid+1, Right);
merge(a, tmpArray, Left, mid+1, Right);
}
}
void mergeSort(vector<int> &a) {
vector<int> tmpArray;
tmpArray.resize(a.size()); // Extra O(n) space
mergeSort(a, tmpArray, 0, a.size() - 1);
}
/*========================Heap Sort============================*/
int LeftChild( int i ) { return ( 2 * ( i ) + 1 );}
void PercDown( vector<int> &A, int i, int N )
{
int Child;
int Tmp;
for( Tmp = A[ i ]; LeftChild( i ) < N; i = Child )
{
Child = LeftChild( i );
if( Child != N - 1 && A[ Child + 1 ] > A[ Child ] )
Child++;
if( Tmp < A[ Child ] )
A[ i ] = A[ Child ];
else
break;
}
A[ i ] =Tmp;
}
void Heapsort(vector<int> &A)
{
if (A.size() <= 1)
return;
int N = A.size();
for( int i = N / 2; i >= 0; i-- ) /* BuildHeap */
PercDown( A, i, N );
for( int i = N - 1; i > 0; i-- )
{
int temp = A[ 0 ];
A[ 0 ] = A[ i ];
A[ i ] = temp; /* DeleteMax and to last position*/
PercDown( A, 0, i );
}
}
};