算法读书笔记第4章
图的这一章我主要学习了广度优先搜索(BFS)和深度优先搜索(DFS),这两种算法主要用于求取路径问题
bfs.c
/** Name: bfs--借助队列实现 Author: Bryant_xw */ #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct graph { int nVertex; int nEdge; int *pMatrix; }Graph; typedef struct node { int nValue; struct node *pNext; }MyQueue; //定义队列 typedef struct queue { int nCount; MyQueue *pHead; MyQueue *pTail; }Queue; void q_Init(Queue **pQueue) { *pQueue = (Queue*)malloc(sizeof(Queue)); (*pQueue)->nCount = 0; (*pQueue)->pHead = NULL; (*pQueue)->pTail = NULL; } void q_Push(Queue *pQueue,int nNum) { if(pQueue == NULL)return; MyQueue *pTemp = NULL; pTemp = (MyQueue*)malloc(sizeof(MyQueue)); pTemp->nValue = nNum; pTemp->pNext = NULL; if(pQueue->pHead == NULL) { pQueue->pHead = pTemp; } else { pQueue->pTail->pNext = pTemp; } pQueue->pTail = pTemp; pQueue->nCount++; } int q_Pop(Queue*pQueue) { if(pQueue == NULL || pQueue->nCount == 0)return -1; MyQueue *pDel = NULL; int nNum; pDel = pQueue->pHead; nNum = pDel->nValue; pQueue->pHead = pQueue->pHead->pNext; free(pDel); pDel = NULL; pQueue->nCount--; if(pQueue->nCount == 0) { pQueue->pTail=NULL; } return nNum; } Graph *CreateGraph() { Graph *pGraph = NULL; pGraph = (Graph*)malloc(sizeof(Graph)); int nV; int nE; printf("请输入顶点个数与边的条数:\n"); scanf("%d%d",&nV,&nE); pGraph->nVertex = nV; pGraph->nEdge = nE; //申请矩阵 pGraph->pMatrix = (int*)malloc(sizeof(int)*nV*nV); memset(pGraph->pMatrix,0,sizeof(int)*nV*nV); int v1,v2; int i; for(i = 0;i<nE;i++) { printf("请输入两个顶点确定一条边:\n"); scanf("%d%d",&v1,&v2); //顶点在合理范围之内 且对应位置未被放置 if(v1 >= 1 && v1 <= nV && v2 >= 1 && v2 <= nV && pGraph->pMatrix[(v1-1)*nV + (v2-1)] == 0) { pGraph->pMatrix[(v1-1)*nV+(v2-1)] = 1; pGraph->pMatrix[(v2-1)*nV+(v1-1)] = 1; } else { i--; } } return pGraph; } void BFS(Graph *pGraph,int nBegin) { if(pGraph == NULL || nBegin <= 0|| nBegin > pGraph->nVertex)return; //申请辅助队列 Queue *pQueue = NULL; q_Init(&pQueue); //标记数组 int *pMark = NULL; pMark = (int*)malloc(sizeof(int)*pGraph->nVertex); memset(pMark,0,sizeof(int)*pGraph->nVertex); //起始顶点入队 q_Push(pQueue,nBegin); pMark[nBegin-1] = 1; while(pQueue->nCount != 0) { //弹出 打印 nBegin = q_Pop(pQueue); printf("%d ",nBegin); //遍历 int i; for(i = 0;i<pGraph->nVertex;i++) { //与其有关的且未被打印过的 if(pGraph->pMatrix[(nBegin-1)*pGraph->nVertex+i] == 1 && pMark[i] == 0) { //入队 标记 q_Push(pQueue,i+1); pMark[i] = 1; } } } } int main() { Graph *pGraph = NULL; pGraph = CreateGraph(); BFS(pGraph,4); return 0; }
dfs.c
/** Name: dfs Author: Bryant_xw */ #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct graph { int nVertex; int nEdge; int *pMatrix; }Graph; Graph *CreateGraph() { Graph *pGraph = NULL; pGraph = (Graph*)malloc(sizeof(Graph)); int nV; int nE; printf("请输入顶点个数与边的条数:\n"); scanf("%d%d",&nV,&nE); pGraph->nVertex = nV; pGraph->nEdge = nE; //申请矩阵 pGraph->pMatrix = (int*)malloc(sizeof(int)*nV*nV); memset(pGraph->pMatrix,0,sizeof(int)*nV*nV); int v1,v2; int i; for(i = 0;i<nE;i++) { printf("请输入两个顶点确定一条边:\n"); scanf("%d%d",&v1,&v2); //顶点在合理范围之内 且对应位置未被放置 if(v1 >= 1 && v1 <= nV && v2 >= 1 && v2 <= nV && pGraph->pMatrix[(v1-1)*nV + (v2-1)] == 0) { pGraph->pMatrix[(v1-1)*nV+(v2-1)] = 1; pGraph->pMatrix[(v2-1)*nV+(v1-1)] = 1; } else { i--; } } return pGraph; } void MyDFS(Graph *pGraph,int nBegin,int *pMark) { //打印 标记 printf("%d ",nBegin); pMark[nBegin-1] = 1; //遍历 int i; for(i = 0;i<pGraph->nVertex;i++) { //找到与当前顶点有关的 且未被打印过的 if(pGraph->pMatrix[(nBegin-1)*pGraph->nVertex + i] == 1 && pMark[i] == 0) { MyDFS(pGraph,i+1,pMark); } } } void DFS(Graph *pGraph,int nBegin) { if(pGraph == NULL || nBegin <= 0 ||nBegin > pGraph->nVertex)return; //标记数组 int *pMark = NULL; pMark = (int*)malloc(sizeof(int)*pGraph->nVertex); memset(pMark,0,sizeof(int)*pGraph->nVertex); MyDFS(pGraph,nBegin,pMark); } int main() { Graph *pGraph = NULL; pGraph = CreateGraph(); DFS(pGraph,5); return 0; }