⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.cpp

📁 读图并输出图的邻接链表
💻 CPP
字号:
/*****************************************
 * file: graph.cpp
 * author: 
 * data : 15:00 2006-11-15
 * copyright: free software & hardware
 * to-do: the implamtation of the graph and it's method
 *****************************************/
#include <stdio.h>
#ifdef WIN32	/* if windows we can use the assert() function */
#	include <assert.h>
#else 
#	define assert(a)
#endif
#include <list>		/* for using the std class list */
#include <vector>	/* for using the std vector class */
#include "graph.h"

/* init the graph 
 * set adj[][] = {0}
 * set size = 0
 */
int init_graph(graph *g)
{
  int i,j;
  assert(g != NULL);
  g->size = 0;
  for(i=0;i<MAX_SIZE;i++)
    for(j=0;j<MAX_SIZE;j++)
      g->adj[i][j] = 0;
  return 0;
}

/* copy the graph s to graph d
 */
int copy_graph(graph *s,graph *d)
{
  d->size = s->size;
  for(size_t i=0;i<s->size; i++){
    for(size_t j=0; j < s->size ; j++){
      d->adj[i][j] = s->adj[i][j];
    }
  }
  return 0;
}
/* read a graph from "graph.txt"
 * Each row of the file represents a link connecting the node on the first and second columns
 */
int read_graph(graph *g)
{
  FILE *fd;
  unsigned int src,dst;
	
  assert(g != NULL);
  fd = fopen("graph.txt","r");
  if( -1 == (int)fd ){
    return -1;	/* error while open the file */
  }
  while( fscanf(fd,"%d %d",&src,&dst) != EOF ){	/* read from the file line by line */
    if(src >= MAX_SIZE || dst >= MAX_SIZE){
      return -1;	/* the number of the bertex must small then 50 */
    }
    if(src >= g->size) g->size = src + 1;	/* get the size */
    if(dst >= g->size) g->size = dst + 1;
    g->adj[src][dst] = 1;	/* so there is a connection between src and dst */
    g->adj[dst][src] = 1;	/* because it is a undirected graph */
  }
  fclose(fd);
  return 0;	/* success return 0 */
}
/* reads the graph structure and prints the graph in the following format: 
 *		v-- a list of its adjacent vertices 
 */
int print_graph(graph *g)
{
  size_t i,j;
	
  assert(g != NULL);
  for(j=0;j<g->size;j++){
    printf("%d -- ",j);
    for(i=0;i<g->size;i++){
      if(g->adj[j][i])	/* if v--i then g->adj[v][i] will equ to 1 */
	printf("%d,",i);
    }
    printf("\n");
  }
  return 0;
}
/* takes a graph G, a source node s, and a destination d as parameters, 
 * and returns the length of the shortest path from s to d. 
 * Bonus:Print the node sequence of the shortest path.
 */
typedef struct _node
{
  int index;			/* vertex index in the graph */
  int father;			/* father's index in the array */
} node;
int shortest_path(graph *g,unsigned int s,unsigned int d) /* use BFS */
{
  std::vector<node> bfs_array;
  unsigned int now_point = 0;		/* the element's index in the bfs_array */
  int is_visited[MAX_SIZE] = {0};	/* the flag array to notify if the vertex has visited */

  assert(g != NULL);
  if(s < 0 || s >= g->size || d < 0 || d >= g->size){ /* use the wrong argument */
    return -1;
  }
  while(1){
    node n;			/* the temp node,use for operation */
    if(bfs_array.size() == 0){	/* have no element we put the first one in it */
      n.index = s;		/* the first element is source vertex "s" */
      n.father = -1;		/* have no father */
      bfs_array.push_back(n);	/* put into array */
      is_visited[s] = 1;	/* now vertex "s" is visited */
      continue;
    }
    for(unsigned int j = 0; j < g->size; j ++){ /* put each one connected to vertex into the array  */
      int vertex = bfs_array[now_point].index;
      if(g->adj[vertex][j] == 1 && is_visited[j] == 0){ /* there is a connection between vertex and j and j has'nt been visited */
	n.index = j;
	n.father = now_point;	/* j's father is vertex, and vertex's index number is now_point */
	bfs_array.push_back(n);
	is_visited[j] = 1;	/* j has been visited */
	if(j == d){
	  now_point = bfs_array.size() - 1 ;
	  goto FINDED;	/* arrive at d!!! */
	}
      }
    }
    now_point ++;
    if(now_point >= bfs_array.size()){ /* there is no element remain */
      break;
    }
  }
  return -1;			/* s not connected with d return -1 */

 FINDED:			/* if s can arrive at d then do the following things */
  int len = 0;
  while(bfs_array[now_point].father != -1 && bfs_array[now_point].index != s){ // print the path one by one
    printf("%d----",bfs_array[now_point].index);
    now_point = bfs_array[now_point].father;
    len ++;	
  }
  printf("%d\n",bfs_array[now_point].index);
  return len;	/* return the length of the path */
}
/* to test the graph g if it is connected 
 * in an other word, if it is a forest
 *  use the algorthm warshall, see the book "introduction to the design & analysis of algorithms"
 */
int is_connected(graph *g)
{
  unsigned int i,j,k;
  graph tmp;

  assert(g != NULL);
  copy_graph (g, &tmp);
  for(k = 0; k < tmp.size ; k++)
    for(i = 0 ; i < tmp.size ; i++)
      for(j = 0 ; j < tmp.size ; j++){
	if(tmp.adj[i][j] == 1) continue;
	if(tmp.adj [i][k] == 1 && tmp.adj [k][j] == 1){
	  tmp.adj [i][j] = 1;
	}
      }
  for(i = 0; i< tmp.size; i++)	/* if the elements in tmp matrix are all 1s then it is connected */
    for(j = 0; j < tmp.size; j++){
      if(tmp.adj [i][j] == 0) return 0;
    }
  return 1;
}
/* to test the graph if it is a tree
 */
int is_tree(graph *g)
{
  assert (g != NULL);
  if(is_connected(g) && !has_cycle(g,0)) /* if the graph is connect and has no cycle then it is a tree */
    return 1;
  return 0;
}
/* to test the graph if it has a cycle,
 * if it has print it
 */
int has_cycle(graph *g,int print)
{
  std::vector<node> bfs_array;
  unsigned int i,now_point = 0;		/* the element's index in the bfs_array */
  int is_visited[MAX_SIZE] = {0};	/* the flag array the notify if the vertex has visited */
  int result = 0;

  while(1){
    node n;			/* the temp node,use for operation */
    if(bfs_array.size() == 0){	/* have no element we put the first one in it */
      for(i=0; i<g->size; i++)
	if(is_visited[i] == 0){
	  n.index = i;		/* the first element is source vertex "s" */
	  n.father = -1;		/* have no father */
	  is_visited[i] = 1;	/* now vertex "s" is visited */
	  bfs_array.push_back(n);	/* put into array */
	  break;
	}
      if(bfs_array.size() == 0) return result;
      continue;
    }
    for(unsigned int j = 0; j < g->size; j ++){ /* put each one connected to vertex into the array  */
      int vertex = bfs_array[now_point].index;
      if(g->adj[vertex][j] == 1 && is_visited[j] == 0){ /* there is a connection between vertex and j and j has'nt been visited */
	n.index = j;
	n.father = now_point;	/* j's father is vertex, and vertex's index number is now_point */
	bfs_array.push_back(n);
	is_visited[j] = 1;	/* j has been visited */
      } else if(g->adj[vertex][j] == 1 && is_visited[j] == 1){
	if(j != bfs_array[now_point].father){ /* there is a cycle */
	  result = 1;
	  if(print == 1){	/* print the cycle */
	    printf("%d",j);
	    int tmp_point = now_point;
	    while(g->adj [ bfs_array[tmp_point].index ][j]  != 1 || tmp_point == now_point){
	      printf ("----%d",bfs_array[tmp_point].index);
	      tmp_point = bfs_array[tmp_point].father;
	    }
	    printf ("----%d",bfs_array[tmp_point].index);
	    printf("----%d\n",j);
	  }
	}
      }
    }
    now_point ++;
    if(now_point >= bfs_array.size()){ /* there is no element remain */
      bfs_array.resize(0);
    }
  }
  return result;			/* s not connected with d return -1 */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -