带权图邻接表实现:用户输入填充vector的问题求助
Hey there! I see you've got a solid start with your weighted graph using an adjacency list (vector of lists of Edge objects) — your manual population works perfectly, so the core structure is sound. The issue with user-input population usually boils down to defining a clear input format and handling the loop logic correctly to map input to your adjacency list structure. Let's break this down with actionable steps and modified code.
Key Input Implementation Ideas
- Define a Clear Input Format: First, decide how users will input graph data. A common, user-friendly approach is:
- Enter the total number of vertices (
N). - Enter the total number of edges (
M). - For each of the
Medges, enter the start vertex ID, end vertex ID, and edge weight.
- Enter the total number of vertices (
- Handle Graph Type: Your manual code builds an undirected graph (each edge is added in both directions), so make sure your input logic mirrors that if you want the same behavior.
- Input Validation: Add basic checks to ensure vertex IDs are within the valid range (0 to N-1) to avoid crashes from out-of-bounds vector access.
Modified Code with User Input
Here's an updated version of your code that includes robust user input handling, with explanations for key changes:
#include <iostream> #include <vector> #include <list> using namespace std; class Edge{ private: double weight; int vertex_id; public: // Use member initializer list for cleaner, more efficient construction Edge(double w, int id) : weight(w), vertex_id(id) {} double getWeight() const { return weight; } int getId() const { return vertex_id; } }; // Separate print function to keep main() clean and reusable void printAdjacencyList(const vector<list<Edge>>& adjList) { int nodeCounter = 0; // Range-based for loops make code more readable than raw iterators for (const auto& nodeEdges : adjList) { cout << "Vertices connected to node: " << nodeCounter << endl; for (const auto& edge : nodeEdges) { cout << " (V = " << edge.getId() << ", weight = " << edge.getWeight() << ")"; } cout << "\n\n"; nodeCounter++; } } int main() { int vertexCount; cout << "Enter number of vertices: "; cin >> vertexCount; // Initialize adjacency list with empty lists for each vertex vector<list<Edge>> adjList(vertexCount); int edgeCount; cout << "Enter number of edges: "; cin >> edgeCount; cout << "Enter each edge as: [start_vertex] [end_vertex] [weight]\n"; for (int i = 0; i < edgeCount; i++) { int start, end; double weight; cin >> start >> end >> weight; // Validate vertex IDs to prevent out-of-bounds errors if (start < 0 || start >= vertexCount || end < 0 || end >= vertexCount) { cout << "⚠️ Invalid vertex ID! Skipping this edge.\n"; continue; } // For undirected graphs: add edge in both directions // emplace_back constructs Edge directly in the list (avoids unnecessary copies) adjList[start].emplace_back(weight, end); adjList[end].emplace_back(weight, start); } // Print the adjacency list to verify input was processed correctly cout << "\n--- Final Adjacency List ---\n"; printAdjacencyList(adjList); return 0; }
Key Improvements & Explanations
- Member Initializer List: The
Edgeconstructor uses this pattern instead of assigning values inside the constructor — it's a cleaner, more efficient C++ practice. - Range-Based For Loops: Replaced raw iterators with range-based loops in the print function to make code more readable and reduce iterator-related bugs.
emplace_backOverpush_back: This method constructs theEdgeobject directly in the list, avoiding unnecessary object copies (better performance thanpush_back(Edge(w, id))).- Input Validation: Basic checks ensure users can't enter invalid vertex IDs, preventing crashes from out-of-bounds vector access.
- Modular Print Function: Moving the print logic to a separate function keeps
main()focused on input handling and makes the print logic reusable elsewhere.
Test with Your Manual Data
If you input the same data as your original manual population:
Enter number of vertices: 4 Enter number of edges: 4 Enter each edge as: [start_vertex] [end_vertex] [weight] 0 1 4 0 2 2 1 2 5 2 3 1
The output will match your original manual adjacency list exactly.
内容的提问来源于stack exchange,提问作者Somerandomguy

