按递增顺序排序图形边缘

时间:2017-03-28 20:12:34

标签: c++ algorithm data-structures graph linked-list

我使用标准邻接列表表示来表示图形,其中每个节点作为链接列表出去。您可以阅读有关邻接列表here的更多信息。

让我们说以下是我的图表:

         10
    0--------1
    |  \     |
   6|   5\   |15
    |      \ |
    2--------3
        4

邻接列表如下所示:

[0,  1,  2,  3]
 |   |   |   |
 10  10  6   6
 |   |   |   |
[1] [0] [0] [2]
 |   |   |   |
 6   15  4   5
 |   |   |   |
[2] [3] [3] [0]
 |   |   |   |
 |   |   |   15
    NULL     |
            [1]
             |
             |
            NULL

由于图形是无向的,因此应该从源到目标以及从目标到源添加边以及边的权重。这就是代码表示在这种情况下的样子。

// Linked list representation
class Adj_Node {
  public:
    int data;
    int weight;
    Adj_Node* next;
};

// Adjacency list representation
class Adj_List {
  public:
    Adj_Node* head;
};

// Graph representation
class Graph {
  public:
    int vertices;
    Adj_List* source;
    Graph(int v) {
      vertices = v;
      source = new Adj_List[vertices];

      for (int i = 0; i < vertices; ++i) {
        source[i].head = NULL;
      }
    }
    void addEdge(int, int, int);
    void printGraph();
};

// Creates an linked list node
Adj_Node* createNode(int d) {
  Adj_Node* tmp = new Adj_Node;
  tmp->data   = d;
  tmp->weight = 0;
  tmp->next   = NULL;

  return tmp;
}

// Adds edge to both src and destination
void Graph::addEdge(int src, int dest, int weight) {
  Adj_Node* node = createNode(dest);
  node->next = source[src].head;
  source[src].head = node;
  node->weight = weight;

  node = createNode(src);
  node->next = source[dest].head;
  source[dest].head = node;
  node->weight = weight;
}

void Graph::printGraph() {
  for(int i = 0; i < vertices; ++i) {
  Adj_Node* n = source[i].head;
  std::cout << i << " = ";
  while(n != NULL) {
    std::cout << n->data << " " << n->weight << ", ";
    n = n->next;
  }
  std::cout << std::endl;
}

因此,在完成上述所有操作后,我在上面描述了链接列表表示,其中图的每个加权边被描述为链表中的节点。 问题是:你建议采用哪种方式来增加顺序?

2 个答案:

答案 0 :(得分:0)

如果额外的空间不是问题,我建议您只使用适当的Edge创建operator<课程,但将边缘放入标准容器中(我会使用std::vector)并使用std::sort对其进行排序。它实际上比实现自己的排序算法更好。

顺便说一句,我没有看到任何理由使用你现在正在使用的结构。如果要将边存储在列表中而不是存储在矢量中,可以使用std::list(具有sort成员函数)而不是重新实现它。

答案 1 :(得分:0)

好。我实施的是这样的:

当我在链接列表中添加节点时,以有序方式添加节点,使链接列表按重量排序。因此,最终的图形描述看起来像:

[0,  1,  2,  3]
 |   |   |   |
 6   10  4   5
 |   |   |   |
[2] [0] [3] [0]
 |   |   |   |
10   15  6   6
 |   |   |   |
[1] [3] [0] [2]
 |   |   |   |
 |   |   |   15
    NULL     |
            [1]
             |
             |
            NULL

然后编写一个遍历所有链表并将值放入向量的迭代器。矢量模板将是:

// First int is weight, second is source, third is destination of the node.
std::vector < std::pair <int, std::pair<int, int> > >::iterator it = vv.begin();

:)在需要的情况下使用向量。