我编写了一个程序,我正在编写一个图形的邻接列表,它完美地工作:
class graph {
private:
Q q;
int v; //no of vertixes
struct node* array; //array of vertixes
public:
...
};
现在我想找到该图表中的组件数量。我编写了这段代码,但在尝试运行findingcomponent()
函数时,它在运行时给出了分段错误错误。
void findingcomponents()
{
int compcount = 0;
int noOfcomp = 0;
node* curr;
for (int i = 0; i < v; i++)
{
curr = array[i].head;
if (curr->next != NULL)
{
while (curr)
{
//while loop for the connected nodes traversel
while (curr)
{
compcount++;
//loop for inner loop traversal and for enque data
if (curr->next->visited != true) //if the next loop of this parent loop is not visited.
{
q.EnQ(curr->next->nodeno);
curr->next->visited = true;
curr = curr->next;
}
else
{
curr = curr->next;
}
}
curr = array[q.deQ()].head;
}
noOfcomp++;
}
}
cout << endl << "There Are : " << noOfcomp << "components in this graph.";
}
其他信息:
节点定义如下:
struct node {
int nodeno;
bool visited;
struct node* next;
struct node* head;
};
我使用Q
类来管理队列。
class Q
{
private:
node* front;
node* roar;
public:
...
int deQ()
{
node * temp = new node;
if (front == NULL){
cout << endl << "\t Queue is Empty";
return NULL;
}
else
{
temp = front;
front = front->next;
return temp->nodeno;
}
}
...
};
答案 0 :(得分:0)
第一个问题:
当您查看邻接列表的头部时,请点击此处:
curr = array[i].head;
您无法确定列表是否为空(即head为nullptr) 所以当你写下一行时:
if (curr->next != NULL)
您可能取消引用空指针,这是未定义的行为,因此可能会触发rutime错误(当您很幸运时)。只要您的节点没有边缘,就会发生这种情况。
下一个问题:
在内部while
循环中,您可以确定curr != nullptr
。这次取消引用是可以的,但您无法确定curr->next
是否为空。所以当你写
if (curr->next->visited != true)
您可能再次取消引用空指针并具有未定义的行为(例如,如果您很幸运,则为段错误)。
使用您提供的数据集,这发生在第一个节点:循环通过邻接列表,并在最后一个元素上触发错误。
其他潜在问题
我没有深入分析您的算法,因为缺少重要的代码。但是我不清楚如何确保所有入队值都出列,并且当队列为空时未调用时q.deQ()
不被调用。
嗯,如果队列为空,在提供的附加代码中,在deQ()
中返回0(NULL
)。但是当遇到节点0时你也会返回0.所以你没有正确处理队列的末尾,冒着永远循环的风险。
因此您必须将此功能更改为:
int deQ()
{
node * temp = new node;
if (front == nullptr) {
cout << endl << "\t Queue is Empty";
return -1; // <======!!!! Normally you should declare a constant for this
}
else {
temp = front;
front = front->next;
return temp->nodeno;
}
}
将它包装在一起:纠正您的功能
void findingcomponents()
{
int compcount = 0;
int noOfcomp = 0;
node* curr;
for (int i = 0; i < v; i++) {
curr = array[i].head;
if (curr == nullptr) { // make sure you don't hit isolated nodes
cout << "isolated node";
}
else if (curr->next != nullptr) {
while (curr) { //while loop for the connected nodes traversel
while (curr) {
compcount++;
//loop for inner loop traversal and for enque data
if (curr->next != nullptr && curr->next->visited != true) //!!!!!!if the next loop of this parent loop is not visited.
{
q.EnQ(curr->next->nodeno);
curr->next->visited = true;
}
curr = curr->next; //!!! this was called at the end of the if, and in an else: just call it systematically.
}
int nodeid = q.deQ(); //!!! here deque and
if (nodeid == -1) //!!! check if a node was found in the quue
curr = nullptr; //!!! if not
else curr = array[nodeid].head;
}
noOfcomp++;
}
}
cout << endl << "There Are : " << noOfcomp << "components in this graph.";
}
请确认组件数量是否正确。我怀疑你以错误的方式增加了计数器。但是你现在还有3个小时的时间来解决它。