我们目前正在研究算法因此我将此问题标记为“家庭作业”,即使这不是与家庭作业相关的任务。为了安全起见。
我们刚研究了随机选择算法,逻辑似乎很简单。从列表中选择一个元素,然后将该元素放在正确的位置。然后在一个子列表中重复该过程,直到索引处的元素到位。其中index是您在排序列表中所需元素的位置。
这应该是快速排序算法的修改版本。但我们只对一个子列表进行排序,而不是两个子列表。因此性能提升(大哦)。
我可以使用外部存储(C ++和基于零的数组)成功实现此算法:
int r_select2(vector<int>& list, int i)
{
int p = list[0];
vector<int> left, right;
for (int k = 1; k < list.size(); ++k)
{
if (list[k] < p) left.push_back(list[k]);
else right.push_back(list[k]);
}
int j = left.size();
if (j > i) p = r_select2(left, i);
else if (j < i) p = r_select2(right, i - j - 1);
return p;
}
但是,我想使用原位(就地)实现算法,而不是使用额外的子数组。我认为这应该是一项简单/琐碎的任务。但在某个地方,我的原位版本出错了。也许现在已经很晚了,我需要睡觉,但我看不出以下版本失败的根本原因:
int r_select(vector<int>& list, int begin, int end, int i)
{
i = i + begin;
int p = list[begin];
if (begin < end)
{
int j = begin;
for (int k = begin + 1; k < end; ++k)
{
if (list[k] < p)
{
++j;
swap(list[j], list[k]);
}
}
swap(list[begin], list[j]);
if (j > i) p = r_select(list, begin, j, i);
else if (j < i) p = r_select(list, j + 1, end, i - j);
}
return p;
}
在这两个示例中,第一个元素被用作枢轴以保持设计简单。在这两个示例中,i
是我想要的元素的索引。
第二个例子失败的任何想法?这是一个简单的逐个错误吗?
谢谢大家!
答案 0 :(得分:2)
这听起来很可疑:
i = i + begin;
...
r_select(list, begin, j, i);