文件结构 :
示例图片 :
文件名字 | 用途 |
CmakeList.txt | cmake文件 |
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 !