假设我使用node
类创建了一些代码:
#include <string>
#include <vector>
using namespace std;
class node
{
vector<node> children;
string name;
};
并假设数据结构在内存中的大小相对较大(例如50 MiB)并且未排序。
我是否有任何合理有效的方法可以根据name
对所有节点进行排序(递归),只需创建一个新的排序树记忆然后丢弃旧副本?
关于分类的澄清:
矢量children
只是根据每个元素name
进行排序。没有其他因素影响排序。
(即这需要我交换两个对象而不进行深度复制 - 这在C ++ 03及更早版本中是否可行?以后怎么办?)
答案 0 :(得分:3)
(即这需要我交换两个对象而不进行深度复制 他们 - 这在C ++ 03及更早版本中是否可行?以后怎么样?)
std::swap
是标准函数。所有标准类型都提供swap
操作作为成员函数。 swap
对于各种算法都是非常常见和必要的。标准std::sort
将使用swap
来交换节点,因此您不必进行深度复制。您只需要实现swap()
。
class node
{
vector<node> children;
string name;
void swap(node& other) {
name.swap(other.name);
children.swap(other.children);
}
void sort() {
std::sort(children.begin(), children.end(), [&](const node& lhs, const node& rhs) {
return lhs.name < rhs.name;
});
std::for_each(children.begin(), children.end(), [&](node& child) {
child.sort();
});
}
};
答案 1 :(得分:1)
虽然我认为计算机模型是正确的(即std::vector<T>
不能成为T
的成员,因为T
不完整),让我们暂时忽略它。相反,我猜你的问题是关于如何移动对象:按原样,
std::sort(children.begin(), children.end(),
predicate);
(使用合适的谓词)将通过std::swap()
交换两个节点的位置。这将创建一个深层复制和两个深度复制分配。简单的解决方法是让std::sort()
使用自定义交换函数,它只是交换子向量:
class node {
...
public:
void swap(node& other) {
this->name.swap(other.name);
this->children.swap(other.children);
};
void swap(node& n0, node& n1) {
n0.swap(n1);
}
通常,对于使用分配(直接或间接)的值类型,您可能希望实现swap()
函数。由于正确行为不需要它,因此通常会在以后添加以获得更好的性能。
答案 2 :(得分:-2)
您可以递归遍历树并在每个节点上使用std :: sort()来重新排序节点。请参阅我已添加到节点的sort()方法。
#include <algorithm>
#include <string>
#include <vector>
class node
{
typedef node storage_t;
typedef std::vector<storage_t> children_t;
children_t children;
std::string name;
struct by_name_fn {
bool operator()(node const& lhs, node const& rhs) const
{
return lhs.name < rhs.name;
}
bool operator()(node const* lhs, node const* rhs) const
{
return lhs->name < rhs->name;
}
};
void sort()
{
std::sort(children.begin(), children.end(), by_name_fn());
typedef children_t::iterator iter_t;
for (iter_t i = children.begin(), e = children.end(); i != e; ++i) {
(*i).sort();
}
}
};
然而,这将进行大量的复制操作。因此,您可能需要更改节点的结构以通过引用而不是通过值包含其子节点。这是将storage_t的typedef调整为node *或某些共享指针,这取决于你的程序的其余部分。您还需要将行(* i).sort()更改为(* i) - &gt; sort()。