Advanced data structure 02 (Figure)

1. Graph traversal

1.1DFS depth traversal (similar to the preorder traversal of binary tree)

Idea:
1. To prevent multiple accesses, set the flag bit; Because there are many nodes, set an array and initialize all of them to 0. If the node has been accessed, set the corresponding subscript element to 1
2. Find the first edge of the current node. If the edge exists, it indicates that there is an adjacent contact, and you can continue to go down
3. After finding the adjacency point, if the subscript is 0, it indicates that it has not been accessed, then it will be accessed recursively until there is no adjacency point
4. If there is no adjacency point, it will fall back. After falling back, it will access the next edge of the previous node

#include<stdio.h>
#include<iostream>

#define maxsize 10

using namespace std;
typedef struct ArcNode //edge
{
	int adjvex;          //The position of the node to which the edge points
	struct ArcNode* next;//Pointer to the next edge
	int info;//
}Edge;
typedef struct VNode
{
	char data;
	ArcNode* firstarc;
};
typedef struct AGraph
{
	VNode adjlist[maxsize];
	int n, e;//Number of vertices and edges
};

int visit[maxsize]; //0 1 2 3 4 visit[1]=1;   Global array
//DFS
void DFS(AGraph* G, int v)//Start number
{
	ArcNode* p;
	visit[v] = 1;
	//	Visit(v);
	p = (G->adjlist[v]).firstarc;
	while (p != NULL)
	{
		if (visit[p->adjvex] == 0)
		{
			DFS(G, p->adjvex);
		}
		p = p->next;
	}
}

1.2BFS breadth traversal (sequence traversal similar to binary tree)

Idea:
1. To prevent multiple accesses, set the flag bit to 0 initially and set the access to 1
2. Queue the first node
3. If the queue is not empty, it will be out of the queue, and the adjacent points of the node will be in the queue at the same time
Specific operations of joining the queue: (first point the pointer to the first edge of the node. If it exists and is not accessed, join the queue, and then access the next edge; if it has been accessed, directly point to the next edge of the node)

/BFS
int visit[maxsize];
void BFS(AGraph* G, int v)
{
	ArcNode* p;
	int que[maxsize], front = 0, rear = 0;
	int j;
	//	Visit(v);
	visit[v] = 1;
	rear = (rear + 1) % maxsize;//Join the team
	que[rear] = v;
	while (front != rear)
	{
		front = (front + 1) % maxsize;//Out of the team
		j = que[front];

		p = G->adjlist[j].firstarc;
		while (p != NULL)
		{
			if (visit[p->adjvex] == 0)
			{
				//	Visit(p->adjvex);
				visit[p->adjvex] = 1;
				rear = (rear + 1) % maxsize;//Adjacent points join the team
				que[rear] = p->adjvex;
			}
			p = p->next;
		}
	}
}

1.3 a little note

When defining a node structure, you will encounter the following forms:
typedef can mask compound types, such as pointers and arrays. For example, it is not necessary to define a character array like this:

char arr[5];
char brr[5];

Whenever you want to use an array of the same type and size, you can:

typedef char Array[5];
Array arr,brr;

so:

typedef struct VNode
{
	int a;
	struct VNode* next;
}Adjlist[maxsize];
Adjlist A;
//Using Adjlist, you can define a structure array with length maxsize. Each element in the array is of type struct VNode

2. Minimum spanning tree (Prim)

Idea:
1. Set node array and minimum weight array
2. Take v0 as the starting point and record it as the value of the weight array
3. Set all nodes to 0 in the array, that is, they are not incorporated into the spanning tree
4. Merge the starting point into the spanning tree, set the initial weight sum to 0, and then accumulate the weight every time
5. In the weight array starting from v, find the smallest weight, incorporate it into the spanning tree, and record the position of its end node
6. Update the weight array with the end node as the starting point
7. Cycle step 56, n-1 times, and N nodes are incorporated into the spanning tree. End!

#define INF 10000000
typedef struct VertexType//Vertex Type 
{
	int no;  //Vertex number
	char info; //Vertex other information
};
typedef struct MGraph  //Adjacency matrix type
{
	int edges[maxsize][maxsize];//Weight of edge
	int n, e;//Number of vertices and edges
	VertexType vex[maxsize];//Node information
};   

void Prim(MGraph g,int v0,int &sum)
{
	int lowcost[maxsize], vset[maxsize], v;
	//The lowcast array is the weight from the spanning tree to the shortest edge of the remaining vertices
	//vset array records the access of vertices. If vset[i]=0, it means that vertex i has not been incorporated into the spanning tree
	int i, j, k, min;
	v = v0;
	for (i = 0; i < g.n; ++i)
	{
		lowcost[i] = g.edges[v0][i];//Weight from vertex to each point
		vset[i] = 0;//Initialization points are not included in the spanning tree
	}
	vset[v0] = 1;//Merge vertices into spanning tree
	sum = 0;//The initial value of the weight is 0
	for (i = 0; i < g.n - 1; ++i)//Control times, update n-1 times
	{
		min = INF;//INF is a constant that is set to be greater than the weight of all edges in the graph
		for (j = 0; j < g.n; ++j)//Select the minimum value of candidate edges starting from v0
		{
			if (vset[j] == 0 && lowcost[j] < min)//Not incorporated and small weight
			{
				min = lowcost[j];//Update min value
				k = j;//Record the serial number of this node
			}
		}
		vset[k] = 1;//Merge the previous node and set it to 1
		v = k;//Record node serial number
		sum += min;//Weight accumulation
		for (j = 0; j < g.n; ++j)//
		{
		//Take the last merged node as the starting point to update the minimum weight
			if (vset[j] == 0 && g.edges[v][j] < lowcost[j])//The weight of the next vertex not incorporated and found from it < the minimum weight recorded
			{
				lowcost[j] = g.edges[v][j];//Minimum weight update (the same end point is updated to the shortest value)
			}
		}
	}
}

3. Topology sorting

The general steps of topology sorting are:
1. Find the node with 0 in degree, output the node and delete the edge of its out degree
2. Repeat 1
Idea:
1. Find the first node with a degree of 0 and put it into the stack
2. If the stack is not empty, exit the stack, and each exit counter + 1
3. The penetration of the adjacent contact of the node needs to be - 1 (the specific operation is: the pointer points to the first edge of the node, if there is an edge, the penetration is - 1, [if the subtraction process is moderate to 0, it will be stacked, and if it is not 0, it will be skipped], the pointer points to the next edge, and the penetration is - 1)
4. If the counter value is equal to the number of summary points, the topology sorting is successful; otherwise, 0 is returned if it fails

//Topological sorting
typedef struct VNode
{
	char data;
	int count;//Penetration of current node
	ArcNode* firstarc;
};

int TopSort(AGraph* G)
{
	int i, j, n = 0;
	int stack[maxsize], top = -1; //Define and initialize
	ArcNode* p;
	for (i = 0; i < G->n; ++i)
	{
		if (G->adjlist[i].count == 0) //The input degree is 0
		{
			stack[++top] = i;//top=top+1; stack[top]=i;
		}
	}
	while (top != -1)  //Stack is not empty
	{
		i = stack[top--];   //Out of stack
		++n;//Counter
		cout << i << " ";
		p = G->adjlist[i].firstarc;
		while (p != NULL) //If there is a vertex in which the edge points, - 1
		{
			j = p->adjvex;
			--(G->adjlist[j].count);
			if (G->adjlist[j].count == 0)//If the degree is 0, it will be put into the stack
			{
				stack[++top] = j;
			}
			p = p->next;
		}
	}
	if (n == G->n)//Stack out once n+1, stack out = = total number is successful
	{
		return 1;
	}
	else
	{
		return 0;
	}
} 

Posted by p_h_p on Sat, 23 Oct 2021 20:34:51 -0700