数据结构邻接表c++

个人学习所记笔记,如有错误请见谅

内容包括邻接表的结构定义,深搜广搜


#include <iostream>
#include <vector>
#include <queue>
using namespace std;

#define MaxVertexNum 100
typedef char VertexType;

//无向邻接表

struct ArcNode {  //边表结点
    int adjvex;  //该弧指向的顶点的位置
    struct ArcNode* nextarc; //指向下一条弧的指针
    int info; //边的权值
};

typedef struct VNode{  //每个边表所连接的结点
    VertexType data;
    ArcNode* firstarc;
}VNode,AdjList[MaxVertexNum];

//邻接表结构,
typedef struct {
    AdjList vertices;
    int vexnum, arcnum;
}ALGraph;

// 初始化图
void InitALGraph(ALGraph& G) {
    G.vexnum = 0;   // 顶点数初始化为 0
    G.arcnum = 0;   // 边数初始化为 0

    // 初始化邻接表
    for (int i = 0; i < MaxVertexNum; i++) {
        G.vertices[i].firstarc = nullptr;  // 每个顶点的邻接表头指针设为 nullptr
    }
}

// 插入顶点
void InsertVertex(ALGraph& G, VertexType vertex) {
    if (G.vexnum >= MaxVertexNum) {
        cout << "图的顶点数已满,无法插入更多顶点!" << endl;
        return;
    }
    G.vertices[G.vexnum].data = vertex;
    G.vertices[G.vexnum].firstarc = nullptr;
    G.vexnum++;
}

// 插入边
void InsertArc(ALGraph& G, int v1, int v2, int weight) {
    if (v1 >= G.vexnum || v2 >= G.vexnum) {
        cout << "顶点索引超出范围!" << endl;
        return;
    }

    // 插入 v2 到 v1 的边
    ArcNode* newArc = new ArcNode;
    newArc->adjvex = v2;
    newArc->info = weight;
    newArc->nextarc = G.vertices[v1].firstarc;
    G.vertices[v1].firstarc = newArc;

    // 插入 v1 到 v2 的边(如果是无向图)
    newArc = new ArcNode;
    newArc->adjvex = v1;
    newArc->info = weight;
    newArc->nextarc = G.vertices[v2].firstarc;
    G.vertices[v2].firstarc = newArc;

    G.arcnum++;
}

// 打印图
void printALGraph(const ALGraph& G) {
    for (int i = 0; i < G.vexnum; i++) {
        cout << "顶点 " << G.vertices[i].data << " 的邻接点有:";
        ArcNode* arc = G.vertices[i].firstarc;   //初始化 arc 为当前顶点 v 的第一个邻接顶点。
        while (arc != nullptr) {
            cout << " (" << G.vertices[arc->adjvex].data << ", 权值: " << arc->info << ")";
            arc = arc->nextarc;
        }
        cout << endl;
    }
}

// 深度优先遍历的递归函数

void DFS(ALGraph& G, int v, vector<bool>& visited) {
    // 访问当前顶点
    cout << G.vertices[v].data << " ";
    visited[v] = true;

    // 遍历当前顶点的所有邻接顶点
    ArcNode* arc = G.vertices[v].firstarc;
    while (arc != nullptr) {
        if (!visited[arc->adjvex]) {
            DFS(G, arc->adjvex, visited);
        }
        arc = arc->nextarc;
    }
}

// 深度优先遍历的入口函数
//这个函数是深度优先遍历的入口点。它遍历图中的所有顶点,
//并确保即使图是非连通的,所有顶点都能被访问到。
void DFSTraverse(ALGraph& G) {
    vector<bool> visited(G.vexnum, false); // 记录每个顶点是否被访问过

    // 遍历所有顶点,防止图中有不连通的部分
    //如果当前顶点 i 尚未被访问,则调用 DFS 从这个顶点开始遍历。
    for (int i = 0; i < G.vexnum; i++) {
        if (!visited[i]) {
            DFS(G, i, visited);
        }
    }
}
//总结
//DFS 函数负责从一个顶点递归地访问所有相邻的未访问顶点。
//DFSTraverse 函数确保了图中的每个顶点都被访问,即使图是非连通的。它通过调用 DFS 函数来实现深度优先遍历。

// 广度优先遍历
void BFS(const ALGraph& G, int startVertex) {
    if (startVertex >= G.vexnum) {
        cout << "起始顶点索引超出范围!" << endl;
        return;
    }

    vector<bool> visited(G.vexnum, false); // 记录顶点是否被访问
    queue<int> q; // 用于 BFS 的队列

    // 从起始顶点开始
    visited[startVertex] = true;
    q.push(startVertex);

    while (!q.empty()) {
        int v = q.front();
        q.pop();
        cout << G.vertices[v].data << " "; // 打印当前顶点

        ArcNode* arc = G.vertices[v].firstarc;
        while (arc != nullptr) {
            if (!visited[arc->adjvex]) {
                visited[arc->adjvex] = true;
                q.push(arc->adjvex);
            }
            arc = arc->nextarc;
        }
    }
    cout << endl;
}


int main()
{
    ALGraph G;
    InitALGraph(G);

    // 示例:插入顶点 A 和 B
    InsertVertex(G, 'A');
    InsertVertex(G, 'B');
    InsertVertex(G, 'C');
    InsertVertex(G, 'D');
    InsertVertex(G, 'E');
    InsertVertex(G, 'F');
    InsertVertex(G, 'G');

    // 示例:插入边 A-B,A-C,B-D,C-D,权值为 10
    InsertArc(G, 0, 1, 10);
    InsertArc(G, 0, 2, 10);
    InsertArc(G, 1, 3, 10);
    InsertArc(G, 1, 4, 10);
    InsertArc(G, 2, 5, 10);
    InsertArc(G, 2, 6, 10);

    // 打印图的结构
    printALGraph(G);

    // 执行深度优先遍历
    cout << "深度优先遍历结果:" << endl;
    DFSTraverse(G);
    cout << endl;

    //执行广度优先遍历:
    cout << "广度优先遍历的结果为:" << endl;
    BFS(G, 0);

    return 0;
}

以下是运行结果

上面是邻接表的显示

下面是深搜和广搜的结果

由于邻接表插入数据是头查,所以遍历结果与普通的邻接矩阵不同,需要仔细研究

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值