您的位置:首页 > 编程语言 > C语言/C++

寻找第k大或第k小的算法 -- 内存足够(C++实现)

2009-10-10 14:45 543 查看
内存足够的情况下,寻找第k大或第k小的算法

1:递归:

template<class T>
T select(T a[], int l, int r, int k)
{
//在a[l:r]中选择第k小的元素
if (l >= r)
return a[l];

int i = l,      // 从左至右的游标
j = r + 1;		// 从右至左的游标
T pivot = a[l];

//把左侧>=pivot的元素与右侧<=pivot的元素进行交换
while (true)
{
do
{
i = i + 1; // 在左侧寻找>=pivot的元素
} while (a[i] < pivot);

do
{
j = j - 1; // 在右侧寻找<=pivot的元素
} while (a[j] > pivot);

if (i >= j)
break;

Swap(a[i], a[j]);
}

if (j - l + 1 == k)
return pivot;

a[l] = a[j];
a[j] = pivot;

if (j - l + 1 < k)
return select(a, j+1, r, k-j+l-1);
else
return select(a, l, j-1, k);
}

template<class T>
T Select(T a[], int n, int k)
{
//返回a[0:n-1]中第k小的元素
//假定a
是一个伪最大元素
if (k < 1 || k > n)
throw OutOfBounds();

return select(a, 0, n-1, k);
}


2:非递归:

template<class T>
T Select2(T a[], int n, int k)
{
//返回a[0:n-1]中第k小的元素
//假定a
是一个伪最大元素
if (k < 1 || k > n)
throw OutOfBounds();

int l = 0;
int r = n - 1;

while (l < r)
{
int i = l,      // 从左至右的游标
j = r + 1;		// 从右至左的游标
T pivot = a[l];

//把左侧>=pivot的元素与右侧<=pivot的元素进行交换
while (true)
{
do
{
i = i + 1; // 在左侧寻找>=pivot的元素
} while (a[i] < pivot);

do
{
j = j - 1; // 在右侧寻找<=pivot的元素
} while (a[j] > pivot);

if (i >= j)
break;

Swap(a[i], a[j]);
}

if (j - l + 1 == k)
return pivot;

a[l] = a[j];
a[j] = pivot;

if (j - l + 1 < k)
{
k -= j - l + 1;
l = j + 1;
}
else
{
r = j - 1;
}
}

return a[l];
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 c++ pivot