【问题标题】:Failed to create adjacency list via one array of singly linked list通过一组单链表创建邻接表失败
【发布时间】:2016-10-15 11:24:09
【问题描述】:

我正在尝试通过一组单链表创建邻接表

查看我的代码。

 #include<iostream>
 #include<cstdlib>

 using namespace std;

 typedef struct city
 {
      int id;
      struct city *next;
 }city;

 int main()
 {
     int num_city, index = 0, length;
     cin >> num_city;   

     length = num_city;

     city **adj_list = new city*[num_city]; // here it's the header node
     for(int index = 0 ; index < length ; index++)
             adj_list[index] = new city;
     city **temp = adj_list;

     while( num_city -- )
     {
             int a,b;
             cin >> a;
             cin >> b;

             a--;
             b--;       

             city *t1 = new city;
             t1 -> id = a;
             t1 -> next = NULL;

             city *t2 = new city;
             t2 -> id = b;
             t2 -> next = NULL;

             temp[a] -> next = t2;
             temp[b] -> next = t1;  

             temp[a] = temp[a] -> next;
             temp[b] = temp[b] -> next;
      } 
      for ( int index = 0; index < length ; index ++)
             delete []  adj_list[index];
      delete [] adj_list;

    adj_list = NULL;
    exit(0);
  }

当我试图逐个遍历单链表时,它的输出是NULL

GDB这段代码之后,我发现:开始循环,city创建成功,adj_list[index]也可以指向正确的内存位置。一旦进入下一个循环,adj_list[index] 就会意外地等于NULL

怎么了?

【问题讨论】:

    标签: c++ arrays singly-linked-list adjacency-list


    【解决方案1】:

    有两个问题。您正在使用temp 来跟踪每个列表中的最后一项。但是temp 指向原始的adj_list(它 adj_list 而不是作为副本如果它),所以结果是adj_list 本身只保留您添加的最后一项每个列表。如果您将初始adj_list 复制到temp,则更新temp 不会影响adj_list 中的现有项目。

    第二个问题是邻居对的数量可能比城市的数量多。以 5 个城市为例:(2,3)、(2,4)、(2,5)、(2,1)、(1,5)、(4,5)、(3,4)。所以你不能循环num_city。而是继续循环,直到用户输入 -1 的城市。

    我添加了一个构造函数city( int id, city* next ),以便更轻松地初始化每个新城市。 temp 重命名为 tail 以更清楚地说明其用途。该功能分为3部分,构建、打印和删除。

    typedef struct city
    {
        int id;
        struct city *next;
        city(int id, city *next) { this->id = id; this->next = next; }
    } city;
    
    // pass `adj_list` in as a reference (city **&) so you keep the changes to it when you return
    int adj_list_build(city **& adj_list)
    {
        int num_city, index = 0;
        cin >> num_city;
    
        // you need to keep track of the "tail" (end) of each list so you know where to add next item
        city **tail = new city*[num_city];
    
        adj_list = new city*[num_city];
        for (int index = 0; index < num_city; index++)
        {
            adj_list[index] = new city( index, NULL );
            tail[index] = adj_list[index]; // the tail starts off pointing to the first item in each list
        }
    
        while (true)
        {
            int a, b;
            cin >> a;               // enter `-1` to stop
            if (a == -1 ) break;
            cin >> b;
    
            a--;                    // convert to 0-index
            b--;
    
            city *t1 = new city( a, NULL );
            city *t2 = new city( b, NULL );
    
            tail[a]->next = t2;
            tail[b]->next = t1;
    
            tail[a] = t2; // or `tail[a] = tail[a]->next;` - they have same effect 
            tail[b] = t1;
        }
        return num_city;
    }
    
    void adj_list_print(city ** adj_list, int length)
    {
        for (int index = 0; index < length; index++)
        {
            cout << index << ": ";
            city * item = adj_list[index];
            while (item)
            {
                cout << item->id << " " << item->next << " ";
                item = item->next;
            }
            cout << endl;
        }
    }
    
    void adj_list_delete(city ** adj_list, int length)
    {
        for (int index = 0; index < length; index++)
            delete[]  adj_list[index];
        delete[] adj_list;
    
        adj_list = NULL;
    }
    
    void main()
    {
        city ** adj_list;
        int len = adj_list_build( adj_list );
        adj_list_print(adj_list, len);
        adj_list_delete(adj_list, len);
    }
    

    【讨论】:

      猜你喜欢
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多