问题1问题问题

#include 
#include 
// 定义SMap类,用于表示邻接表中的节点
class SMap {
public:
    int data;   // 数据域
    SMap* next; // 指针域
    SMap(int v) { // 初始化
        data = v;
        next = nullptr;
    }
    ~SMap() { // 析构函数,正确释放链表后续节点所占用的内存(如果有)
        while (next != nullptr) {
            SMap* temp = next;
            next = next->next;
            delete temp;
        }
    }
    // 插入数据,优化了逻辑,使插入操作更清晰
    void insert(int data) {
        SMap* p = this;  // 创建新节点,将数据插入到链表末尾
        while (p->next != nullptr)
        {
            p = p->next;
        }
        SMap* newNode = new SMap(data);// 创建新节点
        p->next = newNode;
    }
};
// 定义图类
class Graph {
public:
    std::vector<SMap*> adjList;  // 使用vector来动态管理邻接表,更方便内存管理和避免固定大小限制
    int n;
    Graph(int n) {
        this->n = n;
        adjList.resize(n);
    }
    // 添加边
    void addEdge(int u, int v) {
        if (adjList[u] == nullptr) {
            adjList[u] = new SMap(v);
        }
        else {
            adjList[u]->insert(v);
        }
    }
    // 深度优先搜索
    void dfs(int v, bool visited[])
    {
        visited[v] = true; // 标记访问
        std::cout << v << " ";
        SMap* p = adjList[v];
        // 如果同时出现多个待访问的顶点,
        // 则优先选择编号最小的一个进行访问
        int min = v;
        if (p != nullptr) {
            min = p->data;
        }
        while (p != nullptr)
        {
            // 如果该节点没有被访问过,则更新最小值
            if (p->data < min && !visited[p->data])
            {
                min = p->data;
            }
            p = p->next;
        }
        if (!visited[min]) {
            dfs(min, visited);
        }
    }
    // 析构函数,释放邻接表中每个节点所占用的内存
    ~Graph() {
        for (int i = 0; i < n; i++) {
            delete adjList[i];
        }
    }
};
int main() {
    int n, e; // 输入顶点数和边数 其中n不超过20000,e不超过50。
    std::cin >> n >> e;
    if (n > 20000 || e > 50) {
        return 0;
    }
    Graph graph(n);     // 创建有向图
    // 循环边数次
    for (int i = 0; i < e; i++) {
        int u, v; // 输入顶点u指向顶点v
        std::cin >> u >> v;
        if (u >= n || v >= n) {
            return 0;
        }
        graph.addEdge(u, v);// 添加边
    }
    bool* visited = new bool[n]; // 创建访问标记数组
    for (int i = 0; i < n; i++) {
        visited[i] = false;
    }
    for (int i = 0; i < n; i++) {
        if (!visited[i]) {// 如果节点未被访问,则从该节点开始遍历
            graph.dfs(i, visited);
        }
    }
    delete[] visited; // 释放visited数组内存,避免内存泄漏
    return 0;
}

你可能感兴趣的:(c语言)