数据结构图的介绍

     图是一种非线性的数据结构,由节点(顶点)和连接节点的边组成。图可以用来表示各种各样的关系,比如社交网络中的用户之间的关系、地图上的城市之间的道路等。
     图可以分为有向图和无向图。有向图中的边有方向,表示从一个节点到另一个节点的单向关系;无向图中的边没有方向,表示两个节点之间的双向关系。
     图的节点可以包含附加信息,比如在社交网络中的用户节点可以包含用户的个人信息。边可以有权重,表示节点之间的关系的强度或成本。
     图的常用操作包括添加节点、添加边、删除节点、删除边、查找节点、查找边等。
     图的遍历是一种常用的操作,可以按照某种规则依次访问图中的所有节点。深度优先搜索(DFS)和广度优先搜索(BFS)是两种常用的图遍历算法。
     图的应用非常广泛,包括网络路由、社交网络分析、图像处理、推荐系统等领域。在算法和数据结构中,图也是许多经典问题的基础,比如最短路径问题、最小生成树问题等。

以下是图的基本操作和实现代码:

  1. 创建一个图

在创建一个图之前,需要先定义点和边的数据结构。通常使用邻接表或邻接矩阵来表示图。

邻接表实现:

//定义点和边的结构体
struct EdgeNode
{
    int vertex;         //边所连接的点
    int weight;         //边的权重
    EdgeNode* next;     //指向下一条边的指针
};

struct Graph
{
    int numV;           //图中点的数量
    bool isDirected;    //是否为有向图
    EdgeNode** adjList; //邻接表
};

//创建一个点的邻接表
EdgeNode* createEdgeNode(int vertex, int weight)
{
    EdgeNode* node = new EdgeNode;
    node->vertex = vertex;
    node->weight = weight;
    node->next = NULL;
    return node;
}

//创建一个有向图的邻接表
Graph* createDirectedGraph(int numV)
{
    Graph* graph = new Graph;
    graph->numV = numV;
    graph->isDirected = true;
    graph->adjList = new EdgeNode*[numV];
    for (int i = 0; i < numV; i++)
        graph->adjList[i] = NULL;
    return graph;
}

//创建一个无向图的邻接表
Graph* createUndirectedGraph(int numV)
{
    Graph* graph = new Graph;
    graph->numV = numV;
    graph->isDirected = false;
    graph->adjList = new EdgeNode*[numV];
    for (int i = 0; i < numV; i++)
        graph->adjList[i] = NULL;
    return graph;
}

邻接矩阵实现:

//定义点和边的结构体
struct Graph
{
    int numV;           //图中点的数量
    bool isDirected;    //是否为有向图
    int** matrix;       //邻接矩阵
};

//创建一个有向图的邻接矩阵
Graph* createDirectedGraph(int numV)
{
    Graph* graph = new Graph;
    graph->numV = numV;
    graph->isDirected = true;
    graph->matrix = new int*[numV];
    for (int i = 0; i < numV; i++)
    {
        graph->matrix[i] = new int[numV];
        for (int j = 0; j < numV; j++)
            graph->matrix[i][j] = 0;
    }
    return graph;
}

//创建一个无向图的邻接矩阵
Graph* createUndirectedGraph(int numV)
{
    Graph* graph = new Graph;
    graph->numV = numV;
    graph->isDirected = false;
    graph->matrix = new int*[numV];
    for (int i = 0; i < numV; i++)
    {
        graph->matrix[i] = new int[numV];
        for (int j = 0; j < numV; j++)
            graph->matrix[i][j] = 0;
    }
    return graph;
}

  1. 添加一条边

邻接表实现:

//向有向图中添加一条边
void addDirectedEdge(Graph* graph, int src, int dest, int weight)
{
    EdgeNode* node = createEdgeNode(dest, weight);
    node->next = graph->adjList[src];
    graph->adjList[src] = node;
}

//向无向图中添加一条边
void addUndirectedEdge(Graph* graph, int src, int dest, int weight)
{
    EdgeNode* node1 = createEdgeNode(dest, weight);
    EdgeNode* node2 = createEdgeNode(src, weight);
    node1->next = graph->adjList[src];
    graph->adjList[src] = node1;
    node2->next = graph->adjList[dest];
    graph->adjList[dest] = node2;
}

邻接矩阵实现:

//向有向图中添加一条边
void addDirectedEdge(Graph* graph, int src, int dest, int weight)
{
    graph->matrix[src][dest] = weight;
}

//向无向图中添加一条边
void addUndirectedEdge(Graph* graph, int src, int dest, int weight)
{
    graph->matrix[src][dest] = weight;
    graph->matrix[dest][src] = weight;
}

  1. 删除一条边

邻接表实现:

//从有向图中删除一条边
void removeDirectedEdge(Graph* graph, int src, int dest)
{
    EdgeNode* current = graph->adjList[src];
    EdgeNode* prev = NULL;
    while (current)
    {
        if (current->vertex == dest)
        {
            if (prev)
                prev->next = current->next;
            else
                graph->adjList[src] = current->next;
            delete current;
            break;
        }
        prev = current;
        current = current->next;
    }
}

//从无向图中删除一条边
void removeUndirectedEdge(Graph* graph, int src, int dest)
{
    EdgeNode* current = graph->adjList[src];
    EdgeNode* prev = NULL;
    while (current)
    {
        if (current->vertex == dest)
        {
            if (prev)
                prev->next = current->next;
            else
                graph->adjList[src] = current->next;
            delete current;
            break;
        }
        prev = current;
        current = current->next;
    }
    current = graph->adjList[dest];
    prev = NULL;
    while (current)
    {
        if (current->vertex == src)
        {
            if (prev)
                prev->next = current->next;
            else
                graph->adjList[dest] = current->next;
            delete current;
            break;
        }
        prev = current;
        current = current->next;
    }
}

邻接矩阵实现:

//从有向图中删除一条边
void removeDirectedEdge(Graph* graph, int src, int dest)
{
    graph->matrix[src][dest] = 0;
}

//从无向图中删除一条边
void removeUndirectedEdge(Graph* graph, int src, int dest)
{
    graph->matrix[src][dest] = 0;
    graph->matrix[dest][src] = 0;
}

  1. 深度优先遍历

邻接表实现:

//递归函数,用于深度优先遍历
void dfsHelper(Graph* graph, int vertex, bool* visited)
{
    visited[vertex] = true;
    cout << vertex << " ";
    EdgeNode* current = graph->adjList[vertex];
    while (current)
    {
        if (!visited[current->vertex])
            dfsHelper(graph, current->vertex, visited);
        current = current->next;
    }
}

//深度优先遍历
void dfs(Graph* graph, int startVertex)
{
    bool* visited = new bool[graph->numV];
    for (int i = 0; i < graph->numV; i++)
        visited[i] = false;
    dfsHelper(graph, startVertex, visited);
    delete[] visited;
}

邻接矩阵实现:

//递归函数,用于深度优先遍历
void dfsHelper(Graph* graph, int vertex, bool* visited)
{
    visited[vertex] = true;
    cout << vertex << " ";
    for (int i = 0; i < graph->numV; i++)
    {
        if (graph->matrix[vertex][i] != 0 && !visited[i])
            dfsHelper(graph, i, visited);
    }
}

//深度优先遍历
void dfs(Graph* graph, int startVertex)
{
    bool* visited = new bool[graph->numV];
    for (int i = 0; i < graph->numV; i++)
        visited[i] = false;
    dfsHelper(graph, startVertex, visited);
    delete[] visited;
}

  1. 广度优先遍历

邻接表实现:

//广度优先遍历
void bfs(Graph* graph, int startVertex)
{
    bool* visited = new bool[graph->numV];
    for (int i = 0; i < graph->numV; i++)
        visited[i] = false;
    queue q;
    visited[startVertex] = true;
    q.push(startVertex);
    while (!q.empty())
    {
        int vertex = q.front();
        q.pop();
        cout << vertex << " ";


 

你可能感兴趣的:(数据结构)