为什么克鲁斯卡尔算法输出会这样呢

来源:4-8 图的编码实战-最小生成树之克鲁斯卡尔算法(四)

骑着毛驴追太阳

2017-06-06 18:52

http://img.mukewang.com/593689030001d89b12230639.jpg

http://img.mukewang.com/593689030001b59519201039.jpg


下面是我看着老师的视频写的代码,我看了好几遍,没发现有什么不同,但是就是出错,不知道什么原因。

同样的代码,普力马算法就正常


void CMap::kruskalTree()
{
	int value = 0;
	int edgeCount = 0;

	//定义存放结点集合的数组
	vector<vector<int>> nodeSets;

	//第一步:取出所有边
	vector<Edge> edgeVec;
	for (int i = 0; i < m_iCapacity; i++)
	{
		for (int k = i + 1; k < m_iCapacity; k++)
		{
			getValueFromMatrix(i, k, value);
			if (value != 0)
			{
				Edge edge(i, k, value);
				edgeVec.push_back(edge);
			}
		}
	}

	//第二步:从所有边中取出组成最小生成树的边
	//1.找到算法结束条件
	while (edgeCount < m_iCapacity - 1)
	{
		//2.从边集合中找到最小边
		int minEdgeIndex = getMinEdge(edgeVec);
		edgeVec[minEdgeIndex].m_bSelected = true;

		//3.找出最小边连接的点
		int nodeAIndex = edgeVec[minEdgeIndex].m_iNodeIndexA;
		int nodeBIndex = edgeVec[minEdgeIndex].m_iNodeIndexB;

		bool nodeAIsInSet = false;
		bool nodeBIsInSet = false;

		int nodeAInSetLabel = -1;
		int nodeBInSetLabel = -1;

		//4.找出点所在的点集合
		for (int i = 0; i < (int)nodeSets.size(); i++)
		{
			nodeAIsInSet = isInSet(nodeSets[i], nodeAIndex);
			if (nodeAIsInSet)
			{
				nodeAInSetLabel = i;
			}
		}

		for (int i = 0; i < (int)nodeSets.size(); i++)
		{
			nodeBIsInSet = isInSet(nodeSets[i], nodeBIndex);
			if (nodeBIsInSet)
			{
				nodeBInSetLabel = i;
			}
		}

		//5.根据点所在集合的不同做出不同的处理
		if (nodeAInSetLabel == -1 && nodeBInSetLabel == -1)
		{
			vector<int> vec;
			vec.push_back(nodeAIndex);
			vec.push_back(nodeBIndex);
			nodeSets.push_back(vec);
		}
		if (nodeAInSetLabel == -1 && nodeBInSetLabel != -1)
		{
			nodeSets[nodeBInSetLabel].push_back(nodeAIndex);
		}
		if (nodeAInSetLabel != -1 && nodeBInSetLabel == -1)
		{
			nodeSets[nodeBInSetLabel].push_back(nodeBIndex);
		}
		if(nodeAInSetLabel != -1 && nodeBInSetLabel != -1 && nodeAInSetLabel != nodeBInSetLabel)
		{
			mergeNodeSet(nodeSets[nodeAInSetLabel], nodeSets[nodeBInSetLabel]);
			for (int k = nodeBInSetLabel; k < (int)nodeSets.size() - 1; k++)
			{
				nodeSets[k] = nodeSets[k + 1];
			}
		}
		if (nodeAInSetLabel != -1 && nodeBInSetLabel != -1 && nodeAInSetLabel == nodeBInSetLabel)
		{
			continue;
		}

		m_pEdge[edgeCount] = edgeVec[minEdgeIndex];
		edgeCount++;

		cout << edgeVec[minEdgeIndex].m_iNodeIndexA << "--" << edgeVec[minEdgeIndex].m_iNodeIndexB << "  ";
		cout << edgeVec[minEdgeIndex].m_iWeightValue << endl;
	}
}

bool CMap::isInSet(vector<int> nodeSet, int target)
{
	for (int i = 0; i < (int)nodeSet.size(); i++)
	{
		if (nodeSet[i] == target)
		{
			return true;
		}
	}

	return false;
}

void CMap::mergeNodeSet(vector<int> &nodeSetA, vector<int> nodeSetB)
{
	for (int i = 0; i < (int)nodeSetB.size(); i++)
	{
		nodeSetA.push_back( nodeSetB[i] );
	}
}


写回答 关注

1回答

  • SiO
    2017-06-09 17:49:44
    已采纳

    从报错信息上看是容器下标越界的意思就是说你容器的区间传入了错误的值或大或小。

    随后检查了代码在75行处nodeSets[nodeBInSetLabel].push_back(nodeBIndex);下标处应该是nodeAInSetLabel 修改看看可否解决问题。

    骑着毛驴追太...

    非常感谢!

    2017-08-08 17:16:40

    共 1 条回复 >

数据结构探险之图篇

图是众多实际问题解决方案之源,从基础概念入手掌握图的处理

56342 学习 · 81 问题

查看课程

相似问题