【发布时间】:2016-10-07 02:26:55
【问题描述】:
假设我将N 顶点标记为从0 到N-1。每个顶点最多有3 邻居和至少1 邻居。假设邻居信息最初存储在一个名为pairs 的向量中,其中pairs[2*i] 和pairs[2*i+1] 是一对相邻顶点。
现在我需要快速查找vertex[i] 的邻居是什么,存储这些信息的最佳方式是什么?
我想出的方法是:
声明一个名为
neighbors[3*N]的向量,以便neighbors[3*i+0]neighbors[3*i+1]和neighbors[3*i+2]存储三个可能的邻居。为什么说可能,因为每个顶点最多有三个邻居。
-
所以我将向量
neighbors的所有元素初始化为N,这意味着这不是一个有效的邻居,因为顶点的标签是从0到N-1。
代码实现如下:
void get_neighbors(const std::vector<int>& pairs,
std::vector<int>& neighbors) {
int N = neighbors.size()/3;
int M = pairs.size()/2;
//init all the vertexes' neighbours to nothing
for (int i=0; i<3*N; ++i) {
neighbors[i] = N;
}
//loop through all the vertexes, and store their neighbors
for(int i=0; i<N; ++i) {
int j = 0;
//loop through pairs, and find out what neighbors vertex[i] has
for (int k=0; k < M; ++k) {
if(pairs[2*k]==i) {
neighbors[3*i+j]=pairs[2*k+1];
++j;
}
else if(pairs[2*k+1]==i) {
neighbors[3*i+j]=pairs[2*k];
++j;
}
}
}
}
我对我的方法感到不舒服的地方:
声明一个向量
neighbors(3*N)太多了,因为它的许多元素将是无用的N。如果我想查找
vertex[i]的邻居,每次我都需要测试neighbors[3*i]==N、neighbors[3*i+1]==N和neighbors[3*i+2]==N。
【问题讨论】:
-
对从
a到b的每条边使用vector<vector<int> > graph (N);,即b是a的邻居,反之亦然使用:graph[a].push_back (b);这将声明一个@987654351的向量@元素。 因为只有 3 个邻居,所以要获得邻居总是需要恒定的时间。 -
@PRP 你有时间写这个作为答案并提供一些关于
graph的参考吗?我不熟悉符号> graph(N)?您的方法看起来很干净,但是与我的方法相比,查找时间会是多少? -
vector<vector<int>>将比单个向量neighbours有更多的开销;如果 3*N 个元素的开销太大,那么 Nvector<int>s 肯定是太多的开销,因为它会更多的开销。 -
@buzhidao 我在回答中分析了 4 个场景。请选择你认为最好的那个。 在我看来,结构数组解决方案是最好的,我也解释了原因。
-
@PRP 感谢您的详细回答,我会好好检查一下。