使用C++,基于邻接表实现广度优先算法(附源代码)

文件结构 :

示例图片 : 

文件名字用途
CmakeList.txtcmake文件
how.md简述思路以及其他说明
main.cpp主测试程序
AdjacencyList.cpp核心实现文件
AdjacencyList.h

核心头文件

 

AdjacencyMatrix.cpp

//
// Created by A Luck Boy on 2023/2/8.
//

#include "AdjacencyList.h"

NT create(const char *names){
    auto nt = new NT;
    nt->len = 0;
    while (names[nt->len] != '\0') ++nt->len;
    nt->names = new char[nt->len];
    for (int i=0;i<nt->len;i++) {
        nt->names[i] = names[i];
        nt->next[i] = nullptr;
    }
    return * nt;
};

static int getIndex(NT _t, char name){
    for (int i=0;i<_t.len;i++){
        if (_t.names[i] == name) return i;
    }return -1;
};

int getDegree(NT _t, int index){
    int _count = 0;
    auto cur_node = _t.next[index];
    while (cur_node != nullptr){
        _count++;
        cur_node = cur_node->next;
    }
    return _count;
};

int * getAllIndexs(NT _t, char name){
    int _count = 1;
    int * arr = new int[MAXSIZE+1]();
    auto cur_node = _t.next[getIndex(_t, name)];
    while (cur_node != nullptr){
        arr[_count] = cur_node->index;
        cur_node = cur_node->next;
        _count++;
    }
    arr[0] = -1 + _count;
    return arr;
};

void _BFS(NT _t, char name, int * visited, queue<int>& queue){
    // 获取当前起点的索引
    int cur_index = getIndex(_t, name);
    visited[cur_index] = 1;
    cout << "Point " << _t.names[cur_index] <<" is visited !\n";
    queue.push(cur_index);
    // 当队列不是空的时候,说明没有访问完
    while (!queue.empty())
    {
        // 这时候因为当前起点已经被访问而且把与之连接的点标记在辅助数组中了,所以当前点可以从队列删除了
        int firstNumber_Index = queue.front();
        queue.pop();
        // 获取与该点相关的所有连接点的索引
        int * linkedArray = getAllIndexs(_t, _t.names[firstNumber_Index]);
        // 与辅助数组核实,是否每个连接点已经被访问
        // 没有访问就记录到数组和队列
        for (int index=0;index<linkedArray[0];index++){
            if (visited[linkedArray[index+1]] == 0){
                visited[linkedArray[index+1]] = 1;
                // 另外,每一个与当前起点相连的点变成下一个循环的当前点,同上往复操作。
                queue.push(linkedArray[index+1]);
                cout << "Point " << _t.names[linkedArray[index+1]] <<" is visited !\n";
            }
        }
    }
};

void BFS(NT _t, char name){
    int * visited = new int[_t.len]();
    queue<int> queue;
    _BFS(_t, name, visited, queue);
};

AdjacencyMatrix.h

//
// Created by A Luck Boy on 2023/2/8.
//
#include <iostream>
#include <queue>

using namespace std;

// 允许最多点数
#if defined(MAXSIZE)
#else
    #define MAXSIZE 10
#endif
#define SUC cout <<"代码对了!"<<endl;
#define Waring cout<<"代码有误!"<<endl;
#define elif else if

// 每个边点,包含以下属性 :点索引、指向写一个点的指针,与下一个点的权重(方便起见,取整型吧,没有就边就不大于0)
typedef struct Node{
    int index;
    Node * next;
    int weight;
} Node;

// 顶点表,包含顶点名字、顶点数目、各自指向下一个点的指针
// 名字和边点数组的索引都是一样的
typedef struct NTable{
    char *names;
    int len;
    Node * next[MAXSIZE];
} NT;

// methods——不在考虑bug,比如传入xxx参数的检测等等等
// 创建表,传入字符串数组,代表点名字的集合(比如abc代表a、b、c三个点)
NT create(const char *names);

// 查看某个点的索引
static int getIndex(NT _t, char name);

// 计算某个点的度
// index是索引
int getDegree(NT _t, int index);

// 获取与某个点的相连的所有点的的索引组成的数组,数组第一个是长度,没有长度为0,其实也是该点的度
int * getAllIndexs(NT _t, char name);

// BFS——广度优先算法的实现
// 建立一个辅助数组,用来记录已被访问的点。0代表该点没被访问、1代表被访问,其他情况不打算考虑了
// name是你开始遍历的起点
void _BFS(NT _t, char name, int * visited, queue<int>& queue);
void BFS(NT _t, char name);

main.cpp 

//
// Created by A Luck Boy on 2023/2/8.
//
#include "AdjacencyList.h"

int main(){
    // 创建A~H8个点的图
    NT table = create("ABCDEFGH");
    // 按照图示创建表
    Node a_b = {1, nullptr, 1};
    Node a_c = {2, nullptr, 5};
    Node a_f = {5, nullptr, 6};

    Node b_a = {0, nullptr, 1};
    Node b_d = {3, nullptr, 2};

    Node c_a = {0, nullptr, 5};
    Node c_e = {4, nullptr, 4};

    Node d_b = {1, nullptr, 2};
    Node d_e = {4, nullptr, 3};

    Node e_c = {2, nullptr, 4};
    Node e_d = {3, nullptr, 3};

    Node f_a = {0, nullptr, 6};
    Node f_g = {6, nullptr, 8};
    Node f_h = {7, nullptr, 7};

    Node g_f = {5, nullptr, 8};
    Node g_h = {7, nullptr, 9};

    Node h_f = {5, nullptr, 7};
    Node h_g = {6, nullptr, 9};

    table.next[0] = &a_b;
    a_b.next = &a_c;
    a_c.next = &a_f;

    table.next[1] = &b_a;
    b_a.next = &b_d;

    table.next[2] = &c_a;
    c_a.next = &c_e;

    table.next[3] = &d_b;
    d_b.next = &d_e;

    table.next[4] = &e_c;
    e_c.next = &e_d;

    table.next[5] = &f_a;
    f_a.next = &f_g;
    f_g.next = &f_h;

    table.next[6] = &g_f;
    g_f.next = &g_h;

    table.next[7] = &h_f;
    h_f.next = &h_g;

    cout << "len is " << table.len << endl;
    // 查看每个点的度
    for (int i=0;i<table.len;i++) cout<< "Point "<< table.names[i] << " Degree is "<<getDegree(table, i)<<endl;
    // BFS遍历
    BFS(table, 'A');
}

终端运行结果 

len is 8
Point A Degree is 3
Point B Degree is 2
Point C Degree is 2
Point D Degree is 2
Point E Degree is 2
Point F Degree is 3
Point G Degree is 2
Point H Degree is 2
Point A is visited !
Point B is visited !
Point C is visited !
Point F is visited !
Point D is visited !
Point E is visited !
Point G is visited !
Point H is visited !

源代码 :  自己实现的数据结构与算法合集: 自己实现的数据结构与算法合集,使用C或者C++ - Gitee.com

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

若您有别的建议,请在评论区留言

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值