赞
踩
本文给出了一个找到无向图中所有的环的递归算法,该算法是基于DFS(深度优先搜索)的,大概的思路是:在深度优先搜索无向图的过程中,当遇到起始点的时候,会认定为出现环(在本文中只是找出了无向图中所有的长度大于等于3的环(长度为1和2的环没有意思),所以在深搜的过程中,当遇到的是起始点的时候,还需要进行判断是否是环),当确定是出现了环之后,根据是否在遇到环之前的那个点还有其他的路径,来决定是进一步的进行深度优先搜索还是进行回退,在进行深度优先搜索的过程中,将访问过的节点标记,若当前的节点无路可走(不能进行深度优先搜索了),在回退的过程中,将标记取消。算法的过程就下图做简单的介绍:
假设以1为起点进行深度优先搜索,经过访问2,3,4,5,6会得到一个环,因为节点6还有下一条路径可走,此时程序会进入7,8,9,10这些点进行深度优先搜索,但是都再没有回到节点1,于是程序会一层一层的在从7,8,9,10(不一定是这样的顺序)这些点退出来。退至节点6,5,4直到3节点(将6,5,4的标记全部取消)找到了下一条路径5,在走到6,此时又发现了另一条环1->2->3->5->6->1.以此类推。
主要代码如下:
- <span style="font-family:Courier New;font-size:12px;">void DFS(int startVertax)
- {
- setVisitedFlag(startVertax, 1);
- int nextVertax;
- push_stack(&loop_stack, startVertax);
- nextVertax = firstAdjacentVertax(startVertax);
- innerStep++;
- for( ; ; )
- {
- if( nextVertax != -1 )
- {
- if( visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep == 2 ) //从1到2,又从2到1,这不算是一个环
- {
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- continue;
- }
- else if( visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep != 2 ) //找到了一个环
- {
- printf("loop length: %d\t", innerStep);
- print_stack(loop_stack);
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- continue;
- }
- else if( visitedFlag[nextVertax] == 0 )<span style="white-space:pre"> </span>//进行递归
- {
- DFS(nextVertax);
- }
- if( isRecall == 1 ) //进行回退
- {
- innerStep--;
- temp = nextVertax;
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- pop_stack(&loop_stack, &pop_value);
- setVisitedFlag(temp, 0);
- isRecall = 0;
- continue;
- }
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- }
- else if( nextVertax == -1 )
- {
- isRecall = 1;
- break;
- }
- }
- }
- void DFSTraverse()
- {
- initialVisitedFlagArray();
- initializeSequenceStack(&loop_stack);
- int i;
- for( heap = 1; heap <= vertax_size; heap++ )
- {
- for( i = 1; i <= vertax_size; i++ )
- {
- visitedFlag[i] = 0;
- }
- /*
- printf("print the visitedFlag array: ");
- for( i = 1; i <= vertax_size; i++ )
- {
- printf("%d ", visitedFlag[i]);
- }
- printf("\n");
- */
- if( visitedFlag[heap] == 0 )
- {
- printf("\n-------------------the loop start and end with %d----------------\n", heap);
- clear_stack(&loop_stack);
- innerStep = 0;
- isRecall = 0;
- DFS(heap);
- }
- }
- }</span>
- <span style="font-family:Courier New;">#include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<math.h>
-
- int eage_size;
- int vertax_size;
- char filename_eage[200];
- char filename_vertax[200];
-
- int** eage_set;
- char** vertax_set;
- int** adjacentMatrix;
- int* visitedFlag;
-
- typedef struct SequenceStack
- {
- int* base;
- int* top;
- int stackSize;
- }SequenceStack;
-
- void readEageDataFromFile();
- void readVertaxDataFromFile();
- void createAdjacentMatrix();
- void DFS(int);
- void DFSTraverse();
- void initialVisitedFlagArray();
- void printVisitedVertax(int);
- void setVisitedFlag(int,int);
- int firstAdjacentVertax(int);
- int nextAdjacentVertax(int,int);
-
- void initializeSequenceStack(SequenceStack*);
- void pop_stack(SequenceStack*, int*);
- void push_stack(SequenceStack*, int);
- void print_stack(SequenceStack);
- int empty_stack(SequenceStack);
- void clear_stack(SequenceStack*);
- void test_stack();
-
- int main(int argc, char* argv[])
- {
- if( argc != 5 )
- {
- printf("\tThis algorithm require 3 parameters"
- "\n\t\t1:the size of eage"
- "\n\t\t2:the filename contain eage-data"
- "\n\t\t3:the size of vertax"
- "\n\t\t4:the filename contain vertax-data");
- exit(0);
- }
- eage_size = atoi(argv[1]);
- strcat(filename_eage, argv[2]);
- vertax_size = atoi(argv[3]);
- strcat(filename_vertax, argv[4]);
- printf("eage_size : %d, vertax_size : %d, filename-eage : %s, filename-vertax : %s\n", eage_size, vertax_size, filename_eage, filename_vertax);
- readEageDataFromFile();
- readVertaxDataFromFile();
- createAdjacentMatrix();
- DFSTraverse();
- //test_stack();
- return 0;
- }
-
- void readEageDataFromFile()
- {
- FILE* f_read;
- if( NULL == (f_read = fopen(filename_eage, "r")))
- {
- printf("open file(%s) error!\n", filename_eage);
- exit(0);
- }
- //create dynamic array for storing original data form file @filename
- eage_set = (int**)malloc(sizeof(int*) * (eage_size + 1));
- if( !eage_set )
- {
- printf("malloc error: eage_set**\n");
- exit(0);
- }
- int i;
- for( i = 1; i <= eage_size; i++ )
- {
- eage_set[i] = (int*)malloc(sizeof(int) * (2 + 1));
- if( !eage_set[i] )
- {
- printf("eage_set[%d] malloc error", i);
- exit(0);
- }
- }
- //read original data from file
- for( i = 1; i <= eage_size; i++ )
- {
- if( 2 != fscanf(f_read, "%d %d", &eage_set[i][1], &eage_set[i][2]))
- {
- printf("fscanf error: %d\n", i);
- exit(0);
- }
- }
- //test
- printf("\n show the origin data from file\n");
- for( i = 1; i <= eage_size; i++ )
- {
- printf("%d\t%d\n", eage_set[i][1], eage_set[i][2]);
- }
- printf("\n");
- //test END
- }
-
- void readVertaxDataFromFile()
- {
- //create the dynamic array for saving vertax-set information
- vertax_set = (char**)malloc(sizeof(char*) * (vertax_size + 1));
- if( !vertax_set )
- {
- printf("vertax_set malloc error");
- exit(0);
- }
- int i;
- for( i = 1; i <= vertax_size; i++ )
- {
- vertax_set[i] = (char*)malloc(sizeof(char) * (20 + 1));
- if( !vertax_set[i] )
- {
- printf("vertax_set[%d] malloc error");
- exit(0);
- }
- }
-
- //open file
- FILE* f_read;
- if( NULL == (f_read = fopen(filename_vertax, "r")))
- {
- printf("open file(%s) error", filename_vertax);
- exit(0);
- }
-
- //read vertax-set information
- for( i = 1; i <= vertax_size; i++ )
- {
- if( 1 != fscanf(f_read, "%s ", vertax_set[i]) )
- {
- printf("fscanf vertax_set[%d] error", i);
- exit(0);
- }
- }
-
- //test
- for( i = 1; i <= vertax_size; i++ )
- {
- printf("%s\n", vertax_set[i]);
- }
- printf("\n");
- //test END
- }
-
- void createAdjacentMatrix()
- {
- //create the dynamic array for saving adjcaent matrix
- adjacentMatrix = (int**)malloc(sizeof(int*) * (vertax_size + 1));
- if( !adjacentMatrix )
- {
- printf("adjacentMatrix** malloc error");
- exit(0);
- }
- int i;
- for( i = 1; i <= vertax_size; i++ )
- {
- adjacentMatrix[i] = (int*)malloc(sizeof(int) * (vertax_size + 1));
- if( !adjacentMatrix[i] )
- {
- printf("adjacentMatrix[%d] malloc error");
- exit(0);
- }
- }
- //initial the value of adjacentMatrix
- int j;
- for( i = 1; i <= vertax_size; i++ )
- {
- for( j = 1; j <= vertax_size; j++ )
- {
- adjacentMatrix[i][j] = 0;
- }
- }
-
- //set the value for adjacentMatrix
- for( i = 1; i <= eage_size; i++ )
- {
- adjacentMatrix[eage_set[i][1]][eage_set[i][2]] = 1;
- adjacentMatrix[eage_set[i][2]][eage_set[i][1]] = 1;
- }
-
- //test
- printf("\n show the information about adjacent matrix: \n");
- for( i = 1; i <= vertax_size; i++ )
- {
- for( j = 1; j <= vertax_size; j++ )
- {
- printf("%d ", adjacentMatrix[i][j]);
- }
- printf("\n");
- }
- //test END
- }
-
- int loop_count;
- int heap;
- int innerStep = 0;
- int temp;
- int isRecall;
- SequenceStack loop_stack;
- int pop_value;
- void DFS(int startVertax)
- {
- setVisitedFlag(startVertax, 1);
- int nextVertax;
- push_stack(&loop_stack, startVertax);
- nextVertax = firstAdjacentVertax(startVertax);
- innerStep++;
- for( ; ; )
- {
- if( nextVertax != -1 )
- {
- if( visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep == 2 )
- {
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- continue;
- }
- else if( visitedFlag[nextVertax] == 1 && nextVertax == heap && innerStep != 2 )
- {
- print_stack(loop_stack);
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- continue;
- }
- else if( visitedFlag[nextVertax] == 0 )
- {
- DFS(nextVertax);
- }
- if( isRecall == 1 )
- {
- innerStep--;
- temp = nextVertax;
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- pop_stack(&loop_stack, &pop_value);
- setVisitedFlag(temp, 0);
- isRecall = 0;
- continue;
- }
- nextVertax = nextAdjacentVertax(startVertax, nextVertax);
- }
- else if( nextVertax == -1 )
- {
- isRecall = 1;
- break;
- }
- }
- }
- void DFSTraverse()
- {
- initialVisitedFlagArray();
- initializeSequenceStack(&loop_stack);
- int i;
- for( heap = 1; heap <= vertax_size; heap++ )
- {
- for( i = 1; i <= vertax_size; i++ )
- {
- visitedFlag[i] = 0;
- }
- /*
- printf("print the visitedFlag array: ");
- for( i = 1; i <= vertax_size; i++ )
- {
- printf("%d ", visitedFlag[i]);
- }
- printf("\n");
- */
- if( visitedFlag[heap] == 0 )
- {
- printf("\n-------------------the loop start and end with %d----------------\n", heap);
- clear_stack(&loop_stack);
- innerStep = 0;
- //printf("isRecall : %d, findLoop : %d, hasOthers : %d\n", isRecall, findLoop, hasOthers);
- isRecall = 0;
- DFS(heap);
- }
- }
- }
- void initialVisitedFlagArray()
- {
- visitedFlag = (int*)malloc(sizeof(int) * (vertax_size + 1));
- if( !visitedFlag )
- {
- printf("visitedFlag* malloc error");
- exit(0);
- }
- int i;
- for( i = 1; i <= vertax_size; i++ )
- visitedFlag[i] = 0;
- }
- void printVisitedVertax(int vertaxID)
- {
- printf("visited: %d \n", vertaxID);
- }
- void setVisitedFlag(int vertaxID, int value)
- {
- visitedFlag[vertaxID] = value;
- }
- int firstAdjacentVertax(int vertaxID)
- {
- int i;
- for( i = 1; i <= vertax_size; i++ )
- {
- if( adjacentMatrix[vertaxID][i] == 1 )
- return i;
- }
- return -1;
- }
- int nextAdjacentVertax(int vertaxID, int nextVertaxID)
- {
- int i;
- for( i = nextVertaxID + 1; i <= vertax_size; i++ )
- {
- if( adjacentMatrix[vertaxID][i] == 1 )
- return i;
- }
- return -1;
- }
- void initializeSequenceStack(SequenceStack* stack)
- {
- stack->base = (int*)malloc(sizeof(int) * (vertax_size + 1));
- if( !stack->base )
- {
- printf("Sequence stack malloc error!\n");
- exit(0);
- }
- stack->top = stack->base;
- stack->stackSize = vertax_size;
- }
- void pop_stack(SequenceStack* stack, int* value)
- {
- if( empty_stack(*stack) == 1 )
- {
- printf("stack is empty , can not to pop!\n");
- exit(0);
- }
- *value = *(--(stack->top));
- }
- void push_stack(SequenceStack* stack, int value)
- {
- *(stack->top) = value;
- (stack->top)++;
- }
- int empty_stack(SequenceStack stack)
- {
- return stack.top == stack.base ? 1 : 0;
- }
- void print_stack(SequenceStack stack)
- {
- int temp = *(stack.base);
- while( stack.top != stack.base )
- {
- printf("%d->", *((stack.base)++));
- }
- printf("%d\n", temp);
- }
- void clear_stack(SequenceStack* stack)
- {
- stack->top = stack->base;
- }</span>
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。