邻接表c++实现及无权图的单源最短算法

#include <iostream>
#include <queue>
using namespace std;
bool Visited[100] = { false };
#define MaxVertexNum 100/*最大顶点数设为100*/
typedef int Vertex;/*用顶点下标表示顶点,为整形*/
typedef int WeightType;/*边的权值设为整型*/
typedef char DataType;/*顶点存储的数据类型设为字符型*/
/*边的定义*/
typedef struct ENode* PtrToENode;
struct ENode {
    Vertex v1, v2;/*有向边<v1,v2>*/
    WeightType Weight;//权重
};
typedef PtrToENode Edge;
//邻接点的定义
typedef struct AdjVNode* PtrToAdjVNode;
struct AdjVNode {
    Vertex AdjV;//邻接点下标
    WeightType Weight;//边权重
    PtrToAdjVNode Next;//指向下一个邻接点的指针
};
//顶点表头结点的定义
typedef struct VNode {
    PtrToAdjVNode FirstEdge;//边表头指针
    DataType Data;//存顶点的数据
}AdjList[MaxVertexNum];//AdjList是邻接表类型
//图结点的定义
typedef struct GNode* PtrToGNode;
struct GNode {
    int Nv;//顶点数
    int Ne;//边数
    AdjList G;//邻接表
};
typedef PtrToGNode LGraph;//以邻接表方式存储的图类型
LGraph CreateGragp(int VertexNum) {
    //初始化一个有VertexNum个顶点但没有边的图
    Vertex V;
    LGraph Graph;
    Graph = (LGraph)malloc(sizeof(struct GNode));//建立图
    Graph->Nv = VertexNum;
    Graph->Ne = 0;
    //初始化邻接表头指针
    for (V = 0; V < Graph->Nv; V++) {
        Graph->G[V].FirstEdge = NULL;
    }
    return Graph;
}
void InsertEdge(LGraph Graph, Edge E) {
    PtrToAdjVNode NewNode;
    //插入边<v1,v2>
    //为v2建立新的邻接点
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
    NewNode->AdjV = E->v2;
    NewNode->Weight = E->Weight;
    //将v2插入v1的表头
    NewNode->Next = Graph->G[E->v1].FirstEdge;
    Graph->G[E->v1].FirstEdge = NewNode;
    //若是无向图 还要插入边<v2,v1>
    //为v1建立新的邻接点
    NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
    NewNode->AdjV = E->v1;
    NewNode->Weight = E->Weight;
    //将v1插入v2的表头
    NewNode->Next = Graph->G[E->v2].FirstEdge;
    Graph->G[E->v2].FirstEdge = NewNode;
}
LGraph BuildGrapg()
{
    LGraph Graph;
    Edge E;
    Vertex V;
    int Nv, i;
    cin >> Nv;
    Graph = CreateGragp(Nv);
    cin >> Graph->Ne;
    if (Graph->Ne != 0) {
        E = (Edge)malloc(sizeof(struct ENode));
        for (i = 0; i < Graph->Ne; i++) {
            cin >> E->v1 >> E->v2 >> E->Weight;
            InsertEdge(Graph, E);
        }
    }
    //如果顶点有数据 读入数据
    for (V = 0; V < Graph->Nv; V++) {
        cin >> Graph->G[V].Data;
    }
    return Graph;
}
void Visit(Vertex v) {
    printf("正在访问%d\n", v);
}
void Dfs(LGraph Graph, Vertex v, void (*Visit)(Vertex)) {
    //以v为出发点对邻接表存储的图Graph进行DFS搜索
    PtrToAdjVNode W;
    Visit(v);//访问第v个顶点
    Visited[v] = true;//标记已访问
    for (W = Graph->G[v].FirstEdge; W; W = W->Next) {
        if (!Visited[W->AdjV])Dfs(Graph, W->AdjV, Visit);
    }
}
//无权图的单源最短路算法 邻接表存储
/*dist[]和path[]全部初始化为-1*/
int dist[100], paht[100];
void Unweighted(LGraph Graph, int dist[], int path[], Vertex s) {
    for (int i = 0; i < 100; i++) {
        dist[i] = -1;
        path[i] = -1;
    }
    queue<int>q;
    Vertex v;
    PtrToAdjVNode w;
    dist[s]= 0;
    q.push(s);
    while (!q.empty()) {
        v = q.front();
        q.pop();
        for (w = Graph->G[v].FirstEdge; w; w = w->Next) {
            if (dist[w->AdjV] == -1) {
                dist[w->AdjV] = dist[v] + 1;
                path[w->AdjV] = v;
                q.push(w->AdjV);
            }
        }
    }
}

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用邻接表实现Dijkstra算法单源路径的C语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <limits.h> #define MAX_VERTICES 1000 typedef struct Edge { int dest; int weight; struct Edge* next; } Edge; typedef struct Node { Edge* head; } Node; typedef struct Graph { int num_vertices; Node nodes[MAX_VERTICES]; } Graph; Graph* create_graph(int num_vertices) { Graph* graph = (Graph*) malloc(sizeof(Graph)); graph->num_vertices = num_vertices; for (int i = 0; i < num_vertices; i++) graph->nodes[i].head = NULL; return graph; } Edge* create_edge(int dest, int weight) { Edge* edge = (Edge*) malloc(sizeof(Edge)); edge->dest = dest; edge->weight = weight; edge->next = NULL; return edge; } void add_edge(Graph* graph, int src, int dest, int weight) { Edge* edge = create_edge(dest, weight); edge->next = graph->nodes[src].head; graph->nodes[src].head = edge; } int min_distance(int dist[], int visited[], int num_vertices) { int min_dist = INT_MAX, min_vertex; for (int i = 0; i < num_vertices; i++) { if (!visited[i] && dist[i] < min_dist) { min_dist = dist[i]; min_vertex = i; } } return min_vertex; } void print_solution(int dist[], int num_vertices) { printf("Vertex\tDistance from Source\n"); for (int i = 0; i < num_vertices; i++) printf("%d\t%d\n", i, dist[i]); } void dijkstra(Graph* graph, int src) { int dist[MAX_VERTICES]; int visited[MAX_VERTICES]; for (int i = 0; i < graph->num_vertices; i++) { dist[i] = INT_MAX; visited[i] = 0; } dist[src] = 0; for (int i = 0; i < graph->num_vertices - 1; i++) { int u = min_distance(dist, visited, graph->num_vertices); visited[u] = 1; for (Edge* edge = graph->nodes[u].head; edge != NULL; edge = edge->next) { int v = edge->dest; int weight = edge->weight; if (!visited[v] && dist[u] != INT_MAX && dist[u] + weight < dist[v]) dist[v] = dist[u] + weight; } } print_solution(dist, graph->num_vertices); } int main() { int num_vertices = 5; Graph* graph = create_graph(num_vertices); add_edge(graph, 0, 1, 10); add_edge(graph, 0, 4, 5); add_edge(graph, 1, 2, 1); add_edge(graph, 1, 4, 2); add_edge(graph, 2, 3, 4); add_edge(graph, 3, 2, 6); add_edge(graph, 3, 0, 7); add_edge(graph, 4, 1, 3); add_edge(graph, 4, 2, 9); dijkstra(graph, 0); return 0; } ``` 这里实现的Dijkstra算法使用了邻接表来表示,使用了堆排序的思想来寻找当前距离源点最近的未访问过的节点,以提高算法效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值