# PHP of data structure and algorithm using adjacency table and adjacency matrix to realize depth first traversal (DFS) of graph

Keywords: PHP

1, Basic ideas
1) Access the specified starting vertex v;
2) From the adjacency point of v which is not visited, the graph is traversed in depth first, until the vertices which have path communication with v are visited;
3) If there are still vertices in the graph that have not been visited at this time, the depth first traversal is carried out again from a vertex that has not been visited until all the vertices in the graph have been visited.

2, Storage structure of Graphs
Adjacency table storage mode of example graph adjacency matrix storage mode of graph

3, Implementation mode
``````<?php
/**
* Depth first traversal of Graphs
* The storage structure of graph adjacency table
*/
class Node{
public \$value = null;
public \$next = [];//An array that stores the location of the next node

public function __construct(\$value = null){
\$this->value = \$value;
}
}

class Graph
{
// Record whether the node has been traversed
public \$visited = [];
// Adjacency table array of Graphs
public \$graph = [];

/**
* @param \$vertex Vertex v
* @param \$adjvex Adjacency point of vertex v
*/
{
}

// Convert adjacency list array to adjacency list
public function createGraph()
{
\$vertices = array_keys(\$this->graph);
\$result = [];
foreach (\$vertices as \$vertex) {
\$result[\$vertex] = new Node(\$vertex);
}
foreach (\$this->graph as \$vertex => \$adjvex) {
foreach (\$adjvex as \$v) {
if (isset(\$result[\$v]) && is_object(\$result[\$v])) {
\$result[\$vertex]->next[] = \$result[\$v];
}
}
}
return \$result;
}

/**
* recursion
* @param \$v The first vertex to be accessed is passed in
*/
public function dfs(\$v) {
// Set visited flag
\$this->visited[\$v] = 1;
// Output visited vertex
echo \$v . PHP_EOL;
//        print_r(\$this->graph[\$v]);die;
for (\$i = 0; \$i < count(\$this->graph[\$v]); \$i++) {
if (\$this->visited[\$this->graph[\$v][\$i]] == 0) {
\$this->dfs(\$this->graph[\$v][\$i]);
} else {
continue;
}
}
}

/**
* non-recursive
* @param \$v The first vertex to be accessed is passed in
*/
public function deepFirstSearch(\$v) {
// Initialize node traversal flag
\$vertices = array_keys(\$this->graph);
foreach (\$vertices as \$vertex) {
\$this->visited[\$vertex] = 0;
}
\$stack[] = \$v;
while (!empty(\$stack)) {
\$current = array_pop(\$stack);
if (\$this->visited[\$current->value] == 0) {
echo \$current->value . PHP_EOL;
\$this->visited[\$current->value] = 1;
}
for (\$i = count(\$current->next) - 1; \$i >= 0; \$i--) {
if (\$this->visited[\$current->next[\$i]->value] == 0) {
\$stack[] = \$current->next[\$i];
}
}
}
}
}
// test
\$vertices = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8'];
\$g = new Graph();
//print_r(\$g->graph);
// recursion
\$g->dfs(\$vertices[0]);
// non-recursive
\$firstVertex = current(\$g->createGraph());
\$g->deepFirstSearch(\$firstVertex);``````

``````<?php
/**
* Depth first traversal of Graphs
* The storage structure of graph adjacency matrix
*/
class Graph {
// Storage node information
public \$vertices;
// Storage side information
public \$arcs;
// Number of nodes in a graph
public \$vexnum;
// Record whether the node has been traversed
public \$visited = [];

// initialization
public function __construct(\$vertices) {
\$this->vertices = \$vertices;
\$this->vexnum = count(\$this->vertices);
for (\$i = 0; \$i < \$this->vexnum; \$i++) {
for (\$j = 0; \$j < \$this->vexnum; \$j++) {
\$this->arcs[\$i][\$j] = 0;
}
}
}

// Add an edge between two vertices(Undirected graph)
public function addEdge(\$a, \$b) {
if (\$a == \$b) { // The head and tail of an edge cannot be the same node
return;
}
\$this->arcs[\$a][\$b] = 1;
\$this->arcs[\$b][\$a] = 1;
}

// From the i Nodes start depth first traversal
public function traverse(\$i) {
// Mark the i Nodes traversed
\$this->visited[\$i] = 1;
// Print the currently traversed node
echo \$this->vertices[\$i] . PHP_EOL;
// In ergodic adjacency matrix i Direct connection of nodes
for (\$j = 0; \$j < \$this->vexnum ; \$j++) {
// The target node is directly connected with the current node, and the node has not been accessed yet. Recursion
if (\$this->arcs[\$i][\$j] == 1 && \$this->visited[\$j] == 0) {
\$this->traverse(\$j);
}
}
}

// recursion
public function dfs() {
// Initialize node traversal flag
for (\$i = 0; \$i < \$this->vexnum; \$i++) {
\$this->visited[\$i] = 0;
}
// Start deep traversal from nodes not traversed
for (\$i = 0; \$i < \$this->vexnum; \$i++) {
if (\$this->visited[\$i] == 0) {
// If it is a connected graph, it will only be executed once
\$this->traverse(\$i);
}
}
}

// non-recursive
public function deepFirstSearch() {
// Initialize node traversal flag
for (\$i = 0; \$i < \$this->vexnum; \$i++) {
\$this->visited[\$i] = 0;
}
\$stack = [];
for (\$i = 0; \$i < \$this->vexnum; \$i++) {
if (!\$this->visited[\$i]) {
\$stack[] = \$i;
while (!empty(\$stack)) {
// Out of the stack
\$curr = array_pop(\$stack);
// If the node has not been traversed, traverse the node and stack the child nodes
if (\$this->visited[\$curr] == 0) {
echo \$this->vertices[\$curr] . PHP_EOL;
\$this->visited[\$curr] = 1;
// Non traversal child nodes are pushed
for (\$j = \$this->vexnum - 1; \$j >= 0; \$j--) {
if (\$this->arcs[\$curr][\$j] == 1 && \$this->visited[\$j] == 0) {
\$stack[] = \$j;
}
}
}
}
}
}
}
}
// test
\$vertices = ['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'v7', 'v8'];
\$graph = new Graph(\$vertices);
\$graph->addEdge(0, 1); // v1 v2
\$graph->addEdge(0, 2); // v1 v3
\$graph->addEdge(1, 3); // v2 v4
\$graph->addEdge(1, 4); // v2 v5
\$graph->addEdge(2, 5); // v3 v6
\$graph->addEdge(2, 6); // v3 v7
\$graph->addEdge(4, 7); // v5 v8
\$graph->addEdge(3, 7); // v4 v8
// recursion
\$graph->dfs();
// non-recursive
\$graph->deepFirstSearch();``````

Posted by novice@work on Thu, 21 May 2020 08:07:31 -0700