矩阵版本图的深度优先和广度优先遍历

来源:互联网 发布:雷盾网络验证怎么样 编辑:程序博客网 时间:2024/05/22 12:53

链式队列头文件

#ifndef _LINKQUEUE_H_#define _LINKQUEUE_H_typedef void LinkQueue;LinkQueue* LinkQueue_Create();void LinkQueue_Destroy(LinkQueue* queue);void LinkQueue_Clear(LinkQueue* queue);int LinkQueue_Append(LinkQueue* queue, void* item);void* LinkQueue_Retrieve(LinkQueue* queue);void* LinkQueue_Header(LinkQueue* queue);int LinkQueue_Length(LinkQueue* queue);#endif


链式队列实现文件

#include <malloc.h>#include <stdio.h>#include "LinkQueue.h"typedef struct _tag_LinkQueueNode TLinkQueueNode;struct _tag_LinkQueueNode{TLinkQueueNode* next;void* item;};typedef struct _tag_LinkQueue{TLinkQueueNode* front;TLinkQueueNode* rear;int length;}TLinkQueue;LinkQueue* LinkQueue_Create(){TLinkQueue* ret = (TLinkQueue*)malloc(sizeof(TLinkQueue));if (ret != NULL){ret->front = NULL;ret->rear = NULL;ret->length = 0;}return ret;}void LinkQueue_Destroy(LinkQueue* queue){LinkQueue_Clear(queue);free(queue);}void LinkQueue_Clear(LinkQueue* queue){while (LinkQueue_Length(queue) > 0){LinkQueue_Retrieve(queue);}}int LinkQueue_Append(LinkQueue* queue, void* item){TLinkQueue* sQueue = (TLinkQueue*)queue;TLinkQueueNode* node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));int ret = (sQueue != NULL) && (item != NULL) && (node != NULL);if (ret){node->item = item;if (sQueue->length > 0){sQueue->rear->next = node;sQueue->rear = node;node->next = NULL;}else{sQueue->front = node;sQueue->rear = node;node->next = NULL;}sQueue->length++;}if (!ret){free(node);}return ret;}void* LinkQueue_Retrieve(LinkQueue* queue){TLinkQueue* sQueue = (TLinkQueue*)queue;void* ret = NULL;TLinkQueueNode* node = NULL;if ((sQueue != NULL) && (sQueue->length > 0)){node = sQueue->front;sQueue->front = node->next;ret = node->item;free(node);sQueue->length--;if (0 == sQueue->length){sQueue->front = NULL;sQueue->rear = NULL;}}return ret;}void* LinkQueue_Header(LinkQueue* queue){TLinkQueue* sQueue = (TLinkQueue*)queue;void* ret = NULL;if ((sQueue != NULL) && (sQueue->length > 0)){ret = sQueue->front->item;}return ret;}int LinkQueue_Length(LinkQueue* queue){TLinkQueue* sQueue = (TLinkQueue*)queue;int ret = -1;if (sQueue != NULL){ret = sQueue->length;}return ret;}


图的头文件

/****************************************************************版权所有 (C)2014,练习。**文件名称:*内容摘要:*其它说明:*当前版本:*作   者:*完成日期:**修改记录1:  //修改历史记录,包括修改日期、版本号、修改人及修改内容等*   修改日期:*   版本号:*   修改人:*   修改内容:***************************************************************/#ifndef __MGRAPH_H__#define __MGRAPH_H__/**************************************************************相关宏定义**************************************************************//**************************************************************相关结构体定义**************************************************************/typedef void MGraph;//图的结构体定义,数据封装形式typedef void MVertex;//顶点的结构体定义,数据封装形式typedef void (MGraph_printf)(MVertex*);//重命名一个函数类型用来打印信息/**************************************************************创建一个顶点数为n的图,并返回其地址**************************************************************/MGraph* MGraph_Create(MVertex** v, int n);/**************************************************************销毁graph指向的图**************************************************************/void MGraph_Destroy(MGraph* graph);/**************************************************************将graph指向的图清空(清空的是顶点之间的边,而不是顶点本身)**************************************************************/void MGraph_Clear(MGraph* graph);/**************************************************************在graph所指的图中v1和v2之间加上边,且边的权为w**************************************************************/int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);/**************************************************************将graph所指图中v1和v2之间的边删除,返回权值**************************************************************/int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);/**************************************************************将graph所指图中v1和v2之间的边的权值返回**************************************************************/int MGraph_GetEdge(MGraph* graph, int v1, int v2);/**************************************************************将graph所指图中v顶点的度返回**************************************************************/int MGraph_TD(MGraph* graph, int v);/**************************************************************将graph所指图中的顶点数返回**************************************************************/int MGraph_VertexCount(MGraph* graph);/**************************************************************将graph所指图中的边数返回**************************************************************/int MGraph_EdgeCount(MGraph* graph);/****************************************************************************************************************************/void MGraph_DFS(MGraph* graph, int v, MGraph_printf* pFunc);/****************************************************************************************************************************/void MGraph_BFS(MGraph* graph, int v, MGraph_printf* pFunc);/**************************************************************将graph所指图中的顶点之间的关系打印出来**************************************************************/void MGraph_Display(MGraph* graph, MGraph_printf* pFunc);#endif


图的实现文件

/****************************************************************版权所有 (C)2014,公司名称。**文件名称:*内容摘要:*其它说明:*当前版本:*作   者:*完成日期:**修改记录1:   //修改历史记录,包括修改日期、版本号、修改人及修改内容等*   修改日期:*   版本号:*   修改人:*   修改内容:**修改记录2:  //修改历史记录,包括修改日期、版本号、修改人及修改内容等*   修改日期:*   版本号:*   修改人:*   修改内容:***************************************************************//**************************************************************头文件引用**************************************************************/#include <stdio.h>#include <malloc.h>#include "MGraph.h"#include "LinkQueue.h"/**************************************************************全局变量定义**************************************************************/typedef struct _tag_MGraph{int count;//顶点数量MVertex** v;//描述顶点相关数据的指针int** matrix;//(邻阶矩阵)描述顶点之间的边的关系的指针}TMGraph;static void recursive_dfs(TMGraph* graph, int v, int visited[], MGraph_printf* pFunc){int i = 0;pFunc(graph->v[v]);visited[v] = 1;//1表示已经访问过printf(",");for (i = 0; i < graph->count; i++){//(改为矩阵版本的图以后只需要访问二维矩阵的某一行)if ((!visited[i]) && (graph->matrix[v][i] != 0)){recursive_dfs(graph, i, visited, pFunc);}}}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:需要用到队列*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYLLDD            XXX             Name            YYY***********************************************************************/static void recursive_bfs(TMGraph* graph, int v, int visited[], MGraph_printf* pFunc){LinkQueue* queue = LinkQueue_Create();if (queue != NULL){LinkQueue_Append(queue, graph->v + v);//插入的是地址,因为队列里面不能插入0,所以插入地址,后面访问的时候求//相对地址来代表实际的数据,graph->v是基地址visited[v] = 1;//表示已经访问过while (LinkQueue_Length(queue) > 0)//递归结束的条件,全部遍历过{int i = 0;v = (MVertex**)LinkQueue_Retrieve(queue) - graph->v;//将队列里面的数据取出,即访问刚刚插入的节点pFunc(graph->v[v]);printf(",");for (i = 0; i < graph->count; i++)//依次访问下一层(改为矩阵版本的图以后只需要访问二维矩阵的某一行){if ((!visited[i]) && (graph->matrix[v][i] != 0))//如果没有访问过则加入队列以便访问{LinkQueue_Append(queue, graph->v +i);//插入地址visited[i] = 1;//标记已经访问}}}}LinkQueue_Destroy(queue);//有创建必然伴随着销毁}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/MGraph* MGraph_Create(MVertex** v, int n){TMGraph* ret = NULL;if ((v != NULL) && (n > 0)){//有穷非空所以n大于0ret = (TMGraph*)malloc(sizeof(TMGraph));//申请一个头节点对象if (ret != NULL){int* p = NULL;ret->count = n;ret->v = (MVertex**)malloc(sizeof(MVertex*)* n);//申请顶点书据相关的指针空间ret->matrix = (int**)malloc(sizeof(int*)* n);//动态申请二维数组p = (int*)calloc(n * n, sizeof(int));//为了避免二重循环,使用calloc使其自动初始化数据空间if ((ret->v != NULL) && (ret->matrix != NULL) && (p != NULL)){int i = 0;for (i = 0; i < n; i++){ret->v[i] = v[i];//保存顶点的数据指针ret->matrix[i] = p + n*i;//建立一维指针数组到数据空间的链接}}else{//申请不成功要释放空间free(p);free(ret->v);free(ret->matrix);free(ret);ret = NULL;}}}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/void MGraph_Destroy(MGraph* graph){TMGraph* tGraph = (TMGraph*)graph;if (tGraph != NULL){free(tGraph->v);//释放顶点相关的数据空间free(tGraph->matrix[0]);//必须先释放数据空间free(tGraph->matrix);//再释放一维指针数组空间free(tGraph);//最后释放头节点(图本身)}}/***********************************************************************功能描述:清空的是边,而不是顶点*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/void MGraph_Clear(MGraph* graph){TMGraph* tGraph = (TMGraph*)graph;if (tGraph != NULL){int i = 0, j = 0;for (i = 0; i < tGraph->count; i++){for (j = 0; j < tGraph->count; j++){tGraph->matrix[i][j] = 0;}}}}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w){TMGraph* tGraph = (TMGraph*)graph;int ret = (tGraph != NULL);ret = ret && (v1 >= 0) && (v1 < tGraph->count);ret = ret && (v2 >= 0) && (v2 < tGraph->count);ret = ret && (w >= 0);if (ret){tGraph->matrix[v1][v2] = w;}return 0;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_RemoveEdge(MGraph* graph, int v1, int v2){TMGraph* tGraph = (TMGraph*)graph;int ret = MGraph_GetEdge(graph, v1, v2);//代码复用if (ret != 0){tGraph->matrix[v1][v2] = 0;}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_GetEdge(MGraph* graph, int v1, int v2){TMGraph* tGraph = (TMGraph*)graph;int condition = (tGraph != NULL);int ret = 0;condition = condition && (v1 >= 0) && (v1 < tGraph->count);condition = condition && (v2 >= 0) && (v2 < tGraph->count);if (condition){ret = tGraph->matrix[v1][v2];}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_TD(MGraph* graph, int v){TMGraph* tGraph = (TMGraph*)graph;int condition = (tGraph != NULL);int ret = 0;condition = condition && (v >= 0) && (v < tGraph->count);if (condition){int i = 0;for (i = 0; i < tGraph->count; i++){if (tGraph->matrix[v][i] != 0){ret++;}if (tGraph->matrix[i][v] != 0){ret++;}}}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_VertexCount(MGraph* graph){TMGraph* tGraph = (TMGraph*)graph;int ret = 0;if (tGraph != NULL){ret = tGraph->count;}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/int MGraph_EdgeCount(MGraph* graph){TMGraph* tGraph = (TMGraph*)graph;int ret = 0;if (tGraph != NULL){int i = 0, j = 0;for (i = 0; i < tGraph->count; i++){for (j = 0; j < tGraph->count; j++){if (tGraph->matrix[i][j] != 0){ret++;}}}}return ret;}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYLLDD            XXX             Name            YYY***********************************************************************/void MGraph_DFS(MGraph* graph, int v, MGraph_printf* pFunc){TMGraph* tGraph = (TMGraph*)graph;int condition = (tGraph != NULL);int* visited = NULL;condition = condition && (v >= 0) && (v < tGraph->count);condition = condition && (pFunc != NULL);condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);if (condition){int i = 0;recursive_dfs(tGraph, v, visited, pFunc);//表示当V还有相邻的节点未访问时继续深度遍历相邻节点for (i = 0; i < tGraph->count; i++){//表示当v的所有相邻节点已经被访问过,但是图中还有其他节点虽然不与V相邻,//但还未访问过if (!visited[i]){recursive_dfs(tGraph, i, visited, pFunc);}}}free(visited);}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYLLDD            XXX             Name            YYY***********************************************************************/void MGraph_BFS(MGraph* graph, int v, MGraph_printf* pFunc){TMGraph* tGraph = (TMGraph*)graph;int condition = (tGraph != NULL);int* visited = NULL;condition = condition && (v >= 0) && (v < tGraph->count);condition = condition && (pFunc != NULL);condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);if (condition){int i = 0;recursive_bfs(tGraph, v, visited, pFunc);//表示当V还有相邻的节点未访问时继续深度遍历相邻节点for (i = 0; i < tGraph->count; i++){//表示当v的所有相邻节点已经被访问过,但是图中还有其他节点虽然不与V相邻,//但还未访问过if (!visited[i]){recursive_bfs(tGraph, i, visited, pFunc);}}}free(visited);}/***********************************************************************功能描述:*输入参数:*输出参数:*返回值:*其它说明:*修改日期                   版本号          修改人        修改内容* ------------------------------------------------------------------------------------------------------* YYYYMMDD            XXX             Name            YYY***********************************************************************/void MGraph_Display(MGraph* graph, MGraph_printf* pFunc){TMGraph* tGraph = (TMGraph*)graph;if ((tGraph != NULL) && (pFunc != NULL)){int i = 0;int j = 0;for (i = 0; i < tGraph->count; i++){printf("%d:", i);pFunc(tGraph->v[i]);printf(" ");}printf("\n");for (i = 0; i < tGraph->count; i++){for (j = 0; j < tGraph->count; j++){if (tGraph->matrix[i][j] != 0){printf("<");pFunc(tGraph->v[i]);printf(",");pFunc(tGraph->v[j]);printf(",%d", tGraph->matrix[i][j]);printf(">");printf(" ");}}}printf("\n");}}


测试文件

#include <stdio.h>#include <stdlib.h>#include "MGraph.h"/* run this program using the console pauser or add your own getch, system("pause") or input loop */void print_data(MVertex* v){printf("%s", (char*)v);}int main(int argc, char *argv[]){MVertex* v[] = { "A", "B", "C", "D", "E", "F" };MGraph* graph = MGraph_Create(v, 6);MGraph_AddEdge(graph, 0, 1, 1);MGraph_AddEdge(graph, 0, 2, 1);MGraph_AddEdge(graph, 0, 3, 1);MGraph_AddEdge(graph, 1, 5, 1);MGraph_AddEdge(graph, 1, 4, 1);MGraph_AddEdge(graph, 2, 1, 1);MGraph_AddEdge(graph, 3, 4, 1);MGraph_AddEdge(graph, 4, 2, 1);MGraph_Display(graph, print_data);MGraph_DFS(graph, 0, print_data);printf("\n");MGraph_BFS(graph, 0, print_data);printf("\n");MGraph_Destroy(graph);system("PAUSE");return 0;}



0 0
原创粉丝点击