8大ソートアルゴリズム(2)高速ソートの最適化
最も大きな話のデータ構造を見ています.本文の中の最適化内容は基本的にこの本の総括である.コードが少し違うかもしれません.
高速ソートは21世紀の古典的な10大アルゴリズムの一つである.中枢要素を選択し、シーケンス内で中枢位置を一意に決定する方法、すなわち、前のものが中枢値より小さく、後ろのものが中枢値より大きいことを考えます.これにより、並べ替えられるシーケンスを半分に分割します.もちろんこれが一番いい場合、この時の効果が一番いいです.以下3つの側面から最適化する.
最適化されていないソートは次のとおりです.
1.中枢値は、毎回シーケンスの先頭要素として選択されます.可能な限り中間値であることは保証できません.
2.データの並べ替えの場合、小さいデータの場合、直接挿入を使用した並べ替えの方が効果的かもしれません.
3.クイックソートは2つの再帰呼び出しを使用しており、さらに最適化することはできません.
最適化は3つの側面から行います.
1.中枢値を選択します.ここではランダムな方法を採用することができますが、ランダムなシーケンス自体を生成するのに時間がかかり、効果が悪い可能性があります.確率の観点から、ヘッド、中、尾の3つの値を選択します.次に中間値をとります.中枢値としては、効果的です.
高速ソートは21世紀の古典的な10大アルゴリズムの一つである.中枢要素を選択し、シーケンス内で中枢位置を一意に決定する方法、すなわち、前のものが中枢値より小さく、後ろのものが中枢値より大きいことを考えます.これにより、並べ替えられるシーケンスを半分に分割します.もちろんこれが一番いい場合、この時の効果が一番いいです.以下3つの側面から最適化する.
最適化されていないソートは次のとおりです.
void quicksort(int a[],int first,int last)
{
if(first<last)
{
int i=first,j=last;
int tmp=a[first];
while( i<j )
{
while(i<j && a[j]>=tmp)
--j; // find the first index j that a[j] < tmp from right to left
if(i<j)
a[i++]=a[j]; // cover the a[i].
while( i<j && a[i]<tmp)
i++; //find the first index i that a[i]>tmp from left to right
if(i<j)
a[j--]=a[i]; //cover the a[j]
}
if(i==j)
a[i]=tmp;
quicksort(a,first,i-1);
quicksort(a,i+1,last);
}
}
欠点:1.中枢値は、毎回シーケンスの先頭要素として選択されます.可能な限り中間値であることは保証できません.
2.データの並べ替えの場合、小さいデータの場合、直接挿入を使用した並べ替えの方が効果的かもしれません.
3.クイックソートは2つの再帰呼び出しを使用しており、さらに最適化することはできません.
最適化は3つの側面から行います.
1.中枢値を選択します.ここではランダムな方法を採用することができますが、ランダムなシーケンス自体を生成するのに時間がかかり、効果が悪い可能性があります.確率の観点から、ヘッド、中、尾の3つの値を選択します.次に中間値をとります.中枢値としては、効果的です.
/***********************************************************************
QuickSort optimized
1. optimize base value
2. optimize sort scale n
3. optimize the way of recusion (tail recursion)
***********************************************************************/
#include <iostream>
#include <ctime>
using namespace std;
void Swap(int &x,int &y)
{
int tmp=x;
x=y;
y=x;
}
//Unoptimized QuickSort
void quicksort(int a[],int first,int last)
{
while(first<last)
{
int i=first,j=last;
int mid=(first+last)/2; //mid value
if(a[first]>a[last])
Swap(a[first],a[last]); // ensure index pos=first value less than last
if(a[mid]>a[last])
Swap(a[mid],a[last]); // ensure index pos=mid value less than last
if(a[first]>a[mid])
Swap(a[first],a[mid]); // ensure first val less than mid
int tmp=a[first]; //now a[first] is the mid-value of low -mid-high
while( i<j )
{
while(i<j && a[j]>=tmp)
--j; // find the first index j that a[j] < tmp from right to left
if(i<j)
a[i++]=a[j]; // cover the a[i].
while( i<j && a[i]<tmp)
i++; //find the first index i that a[i]>tmp from left to right
if(i<j)
a[j--]=a[i]; //cover the a[j]
}
if(i==j)
a[i]=tmp;
quicksort(a,first,i-1);
first=i+1; //reduce one recursion
//quicksort(a,i+1,last);
}
}
void QuickSort(int a[],int len)
{
if(len>32)
quicksort(a,0,len-1);
//else // when data scale less than 32 use InsertSort
// InsertSort(a,len);
}
void print(int a[],int len)
{
for(int i=0;i<len;i++)
printf("%d ",a[i]);
printf("
");
}
int main()
{
srand(time(NULL));
const int MAX=1000;
int a[MAX];
for(int i=0;i<MAX;i++)
a[i]=rand();
clock_t timebegin=clock();
QuickSort(a,MAX);
clock_t timeend=clock();
//cout<<" :\t"<<timeend-timebegin<<"ms"<<endl;
print(a,MAX);
}