c++ - 就地随机选择算法

标签 c++ algorithm random selection

我们目前正在研究算法,因此我将这个问题标记为“家庭作业”,尽管这不是与家庭作业相关的任务。只是为了安全。

我们刚刚研究了随机选择算法,逻辑似乎很简单。从列表中选择一个元素,然后将该元素放在正确的位置。然后在一个子列表中重复该过程,直到索引处的元素就位。其中索引是您想要的元素在排序列表中的位置。

这应该是快速排序算法的修改版。但是我们只对一个子列表进行排序,而不是对两个子列表进行排序。因此性能提升(大哦)。

我可以使用外部存储(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;
}

但是,我想使用原位(in-place)实现算法,而不是使用额外的子数组。我相信这应该是一项简单/微不足道的任务。但是在某个地方,我的原位版本出错了。可能是时间太晚了,我需要 sleep 了,但是我看不到以下版本失败的根本原因:

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 是我想要的元素的索引。

第二个例子失败的地方有什么想法吗?这是一个简单的差一错误吗?

谢谢大家!

最佳答案

这听起来很可疑:

i = i + begin;
...
r_select(list, begin, j, i);

关于c++ - 就地随机选择算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9916535/

相关文章:

python - 为什么这个算法对于不是 2 的幂的整数会失败?

php - 来自数据库的随机数据

c++ - Qt:绘制高 DPI QPixmaps

c++ - 我的代码在 Qt 中的 Debug模式下工作时不能在 Release模式下工作

c++ - 算法到计算模式

javascript - 同步随机变量

text - 在哪里可以获得几乎所有英语单词的列表?

c++ - 默认 move 语义与复制是否一样?

java - 调用函数时 JNI C++ android 应用程序崩溃

python - 在python中从数组中查找最佳元素