图BFS中的组件查找

时间:2015-11-16 21:46:28

标签: c++ pointers graph components breadth-first-search

我编写了一个程序,我正在编写一个图形的邻接列表,它完美地工作:

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;
            }
    }
...
}; 

1 个答案:

答案 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个小时的时间来解决它。