余祥宣, 崔国华, 邹海明. 计算机算法基础.3版[M]. 华中科技大学出版社, 2006.
P96 算法4.17
#include<iostream>
#include<time.h>
#include<windows.h>
using namespace std;
const int r=5;//步长
void InterChange(int&a, int&b)
{
int temp = a;
a = b;
b = temp;
}
void InsertionSort(int A[], int start, int end)
{
for (int j = start + 1; j <= end; j++)
{
int item = A[j];
int i = j - 1;
while (i>=start&&item < A[i])
{
A[i + 1] = A[i];
i--;
}
A[i + 1] = item;
}
}
int Partition(int A[], int m, int p)//A[p+1]=无穷大
{
int i, v;
v = A[m];
i = m;
while (true)
{
do
{
i = i + 1;
} while (A[i] < v);
do
{
p = p - 1;
} while (A[p] > v);
if (i < p)
{
InterChange(A[i], A[p]);
}
else
{
break;
}
}
A[m] = A[p];
A[p] = v;
return p;
}
void ShowList(int A[], int length=12)
{
for (int i = 0; i<length; i++)
cout << i << "=>" << A[i] << "\t";
cout << endl;
}
int SEL(int A[],int m,int p,int k)
{
int n, i, j;
while (true)
{
n = p - m + 1;
if (p - m + 1 <= r)
{
InsertionSort(A, m, p);
return m + k - 1;
}
int nr_down = n / r;// n/r向下取整
for (i = 1; i <= nr_down; i++)
{
InsertionSort(A, m + (i - 1)*r, m + i*r - 1);
InterChange(A[m + i - 1], A[m + (i - 1)*r + (r + 2 - 1) / 2 - 1]);//中间值应该是r/2向上取整
}
//向上取整(a+b-1)/b
//A[m,m+1,……,m+nr_down - 1]取中值即长度/2向上取整
j = SEL(A, m, m + nr_down - 1, (nr_down + 2 - 1) / 2);
//使用Partition(A,m,j)要做出调整
InterChange(A[m], A[j]);
j = p + 1;
int temp = A[p + 1];
A[j] = INT_MAX;
j=Partition(A,m,j);
A[p + 1] = temp;
if (j - m + 1 == k)
{
return j;
}
else if (j - m + 1 > k)
p = j - 1;
else
{
k = k - (j - m + 1);
m = j + 1;
}
}
}
int main()
{
const int len = 10;//数据量
int a[len];
int b[len];
srand((unsigned)time(NULL));
for (int i = 0; i < len; i++)
a[i]=b[i] = rand()%100000+1;
DWORD start, end;
int index = rand() % len+ 1;//索引位置
int key = 0;
start = GetTickCount();
key = SEL(a, 0, len-1,index);
start = GetTickCount();
cout << "Time:" << end - start << endl;
ShowList(a, len);
cout << endl <<" a["<<key<<"]"<<a[key]<<endl;
start = GetTickCount();
InsertionSort(b, 0, len - 1);
start = GetTickCount();
cout << "Time:" << end - start << endl;
ShowList(b, len);
cout << endl << " b[" << index-1 << "]" << a[index-1];
system("pause");
return 0;
}
运行结果