首先,归并排序,分治。递归解决小的范围。再合并两个有序的小范围数组,便得到整个有序的数组。
这是非常适合用递归来写的。至于非递归。便是从小到大。各个击破,从而使得整个数组有序。代码例如以下:
void merge(vector<int> &A, int left, int mid, int right)
{
int i=left,j=mid+1;
vector<int> tmp(right-left+1,0);
int k=0;
while(i<=mid&&j<=right)
{
if(A[i] < A[j]) tmp[k++]=A[i++];
else tmp[k++]=A[j++];
}
while(i<=mid)tmp[k++]=A[i++];
while(j<=right)tmp[k++]=A[j++];
//write to A
for(int i=0;i<right-left+1;++i)
{
A[left+i]=tmp[i];
}
}
void mergeSort(vector<int> &A)
{
const int n=A.size();
int step=1;
int left=0,right,mid;
while(step< n)
{
left=0;
while(left+step<n)
{
mid=left+step-1;
right=mid+step;
if(right>=n) right=n-1;
merge(A,left,mid,right);
left=right+1;
}
step *= 2;
}
}
int partition(vector<int> &A, int left, int right)
{
int pivot=A[right];
int i=left;
for(int k=left;k<right;++k)
{
if (A[k] < pivot) swap(A[i++],A[k]);
}
swap(A[i],A[right]);
return i;
}
void quickSort(vector<int> &A)
{
stack<pair<int,int> > s;
const int n = A.size();
if(n <2 ) return;
int left=0,right=n-1;
s.push(make_pair(left, right));
while(!s.empty())
{
auto cur=s.top();s.pop();
left=cur.first;right=cur.second;
if(left>=right)continue;
int mid=partition(A,left,right);
s.push(make_pair(left, mid-1));
s.push(make_pair(mid+1, right));
}
}
写习惯了这两种排序的递归版本号,此处的非递归版本号确实不是那么自然而然的,可是仅仅要记住递归的版本号一定能够使用栈来模拟递归的过程,那么我们相同能够实现非递归的版本号,此文就是一份备忘吧。