这是使用邻接列表实现无向图的正确方法吗?

时间:2015-10-01 14:29:23

标签: c++ arrays list graph

首先,我是graph的新手。在研究了graph的概念后,我想到了用c ++实现。当我搜索实现时,我觉得很难理解代码,所以我想实现自己。

以下是我试过的代码:

#include<iostream>
using namespace std;

struct Node {
    int data;
    Node *link;

};

//creating array of nodes
struct Node *array[10];
//creating array of head pointers to point each of the array node.
struct Node *head[10];
//creating array of current pointers to track the list on each array node.
struct Node *cur[10];

void create(int v)
{

    for (int i = 0; i < v; i++) {
        array[i] = new Node;
        head[i] = cur[i] = array[i];
        array[i]->data = i;
        array[i]->link = NULL;
    }

}

void add(int fr, int to)
{
    Node *np = new Node;
    np->data = to;
    np->link = NULL;

    if (head[fr]->link == NULL) {
        head[fr]->link = np;
        cur[fr] = np;

    } else {
        cur[fr]->link = np;
        cur[fr] = np;
    }

    /*Node* np1=new Node;
    np1->data=fr;
    np1->link=NULL;
    if(head[to]->link==NULL)
    {
    head[to]->link=np1;
    cur[to]=np1;
    }else
    {
    cur[to]->link=np1;
    cur[to]=np1;
    }*/

}

void print(int a)
{
    Node *p = NULL;
    p = head[a];

    for (; p != NULL; p = p->link)
    { cout << p->data; }

}



main()
{

    int a;
    cout << "enter the size of array";
    cin >> a;
    create(a);
    //adding edges
    add(1, 4);
    add(1, 3);
    add(0, 3);
    add(0, 2);
    print(0);
    cout << "\n";
    print(1);
    //print(3);

}

说明:

1)要求用户输入一个整数(顶点数),因此我创建了一个请求大小的数组。同时我指向每个数组节点的head和cur指针。数组的索引号等于顶点数。

2)通过add函数将一个顶点的边添加到另一个顶点。如果边缘发出的顶点的头节点为空,则i指向head = cur = new node(np),否则我在每次添加后更新cur指针。 Head将指向数组索引节点。 3)打印连接到请求节点的边缘。

我的问题是:

1)这种实施方式是否正确?

2)在上面的例子中假设我们连接顶点1和顶点3.上面的code3链接到1.我想自动更新从顶点3到顶点1的连接,所以我添加了里面的代码添加功能的注释部分。当我尝试运行代码时,它要求我输入数组的大小,我输入一些整数,它显示我的分段错误。为什么呢?

2 个答案:

答案 0 :(得分:0)

我会试着给你一个想法。

在无向图中,每个节点都可以连接到任何其他节点。 这意味着节点“指向”任意数量的其他节点。 在您的代码中,每个节点都有Node*link;,它是指向下一个节点的指针。您需要一个列表(或数组)链接:每个节点必须包含指向它所连接的所有节点的链接。这是邻接列表。像

这样的东西
struct Node
{
    int data;
    ADJ* adjs; // list of Node*
};

struct ADJ
{
    ADJ* next;
    Node* data;
};

这里adjs是邻接列表。

此外,void print(int a)的解决方案与您在常用列表中找到的解决方案更相似。您需要打印节点的所有邻接,即它指向的所有节点。

请记住,由于图表是无向的,因此您需要使用pointert A-&gt; B和B-&gt; A

答案 1 :(得分:0)

调用create(3)后,您的数组看起来如下所示:

array  
0 -> (0,NULL)
1 -> (1,NULL)
2 -> (2,NULL)
3
4
5
6
7
8
9 

调用add(1,4)时发生分段错误。

在第一部分,即

Node *np = new Node;
np->data = to;
np->link = NULL;

if (head[fr]->link == NULL) {
    head[fr]->link = np;
    cur[fr] = np;

} else {
    cur[fr]->link = np;
    cur[fr] = np;
}

完全没问题。

现在数组看起来如下所示:

array  
0 -> (0,NULL)
1 -> (1,->) (4,NULL)
2 -> (2,NULL)
3
4
5
6
7
8
9

但Next部分是分段错误的原因,即

Node* np1=new Node;
np1->data=fr;
np1->link=NULL;
if(head[to]->link==NULL)
{
head[to]->link=np1;
cur[to]=np1;
}else
{
cur[to]->link=np1;
cur[to]=np1;
}

问题在于这一行:

head[to]->link==NULL

这里的值为4表示你的代码尝试访问头部[4]的部分链接,但是头部[4]没有存储有效节点的地址。