MGraph图(代码、分析、汇编)
生活随笔
收集整理的這篇文章主要介紹了
MGraph图(代码、分析、汇编)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
目錄:
- 代碼:
- 分析:
- 匯編:
MGrapth圖表示有鄰接矩陣的方式構(gòu)成的圖結(jié)構(gòu)。
鄰接矩陣用兩個(gè)數(shù)組保存數(shù)據(jù),一個(gè)一維數(shù)組存儲(chǔ)圖中的頂點(diǎn)信息,一個(gè)二維數(shù)組存儲(chǔ)圖中邊或弧的信息。
無向圖中的二維數(shù)組是個(gè)對(duì)稱矩陣
1.0表示無邊,1表示有邊
2.頂點(diǎn)的度是行內(nèi)數(shù)組之和
3.求取頂點(diǎn)鄰接占,將行內(nèi)元素遍歷下
有向圖的鄰接矩陣(二維數(shù)組),
有分入度和出度,行內(nèi)之和是出度,列內(nèi)之和是入度
代碼:
LinkQueue.h
#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);#endifLinkQueue.c
#include <malloc.h> #include <stdio.h> #include "LinkQueue.h"typedef struct _tag_LinkQueueNode TLinkQueueNode;//定義隊(duì)列節(jié)點(diǎn)類型 struct _tag_LinkQueueNode {TLinkQueueNode* next;void* item; };typedef struct _tag_LinkQueue//定義隊(duì)列類型 {TLinkQueueNode* front;TLinkQueueNode* rear;int length; } TLinkQueue;LinkQueue* LinkQueue_Create() //定義創(chuàng)建隊(duì)列函數(shù) {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) // 定義銷毀隊(duì)列函數(shù) {LinkQueue_Clear(queue);free(queue); }void LinkQueue_Clear(LinkQueue* queue) // 定義清空隊(duì)列函數(shù) {while( LinkQueue_Length(queue) > 0 ){LinkQueue_Retrieve(queue);} }int LinkQueue_Append(LinkQueue* queue, void* item) // 定義進(jìn)隊(duì)列函數(shù) {TLinkQueue* sQueue = (TLinkQueue*)queue;//取得隊(duì)列TLinkQueueNode* node = (TLinkQueueNode*)malloc(sizeof(TLinkQueueNode));//新建節(jié)點(diǎn)int ret = (sQueue != NULL ) && (item != NULL) && (node != NULL);if( ret ){node->item = item;//給新建節(jié)點(diǎn)保存的數(shù)據(jù)賦值if( sQueue->length > 0 )//如果長度大于0{sQueue->rear->next = node;//將隊(duì)列最后一個(gè)節(jié)點(diǎn)的next指向新建節(jié)點(diǎn)sQueue->rear = node;//設(shè)新建節(jié)點(diǎn)為最后節(jié)點(diǎn) node->next = NULL;}else//否則 表示是第一個(gè)節(jié)點(diǎn){sQueue->front = node;//設(shè)第一個(gè)節(jié)點(diǎn)為新建節(jié)點(diǎn)sQueue->rear = node;//設(shè)最后一個(gè)節(jié)點(diǎn)為新建節(jié)點(diǎn)node->next = NULL;}sQueue->length++;}if( !ret )//條件不成功{free(node);//釋放新建節(jié)點(diǎn)}return ret; }void* LinkQueue_Retrieve(LinkQueue* queue) // 定義出隊(duì)列函數(shù) {TLinkQueue* sQueue = (TLinkQueue*)queue;//取得隊(duì)列TLinkQueueNode* node = NULL;void* ret = NULL;if( (sQueue != NULL) && (sQueue->length > 0) ){node = sQueue->front;//取得出隊(duì)列節(jié)點(diǎn)sQueue->front = node->next;//將隊(duì)列第一個(gè)節(jié)點(diǎn)設(shè)為取出節(jié)點(diǎn)的下一個(gè)ret = node->item;//取得節(jié)點(diǎn)保存的數(shù)據(jù)free(node);//釋放出隊(duì)列節(jié)點(diǎn)sQueue->length--;if( sQueue->length == 0 )//如果是最后一個(gè)節(jié)點(diǎn){sQueue->front = NULL;//將第一個(gè)節(jié)點(diǎn)指針清空sQueue->rear = NULL;//將最后一個(gè)節(jié)點(diǎn)指針清空}}return ret; }void* LinkQueue_Header(LinkQueue* queue) // 定義獲取第一個(gè)節(jié)點(diǎn)數(shù)據(jù)函數(shù) {TLinkQueue* sQueue = (TLinkQueue*)queue;void* ret = NULL;if( (sQueue != NULL) && (sQueue->length > 0) ){ret = sQueue->front->item;}return ret; }int LinkQueue_Length(LinkQueue* queue) // 定義獲取隊(duì)列長度函數(shù) {TLinkQueue* sQueue = (TLinkQueue*)queue;int ret = -1;if( sQueue != NULL ){ret = sQueue->length;}return ret; }MGraph.h
#ifndef _MGRAPH_H_ #define _MGRAPH_H_typedef void MGraph;//定義圖類型 typedef void MVertex;//定義頂點(diǎn)類型 typedef void (MGraph_Printf)(MVertex*);//定義有一個(gè)頂點(diǎn)類型指針參數(shù)并且無返回值的函數(shù)類型MGraph* MGraph_Create(MVertex** v, int n);//聲明創(chuàng)建圖函數(shù)void MGraph_Destroy(MGraph* graph);//聲明銷毀圖函數(shù)void MGraph_Clear(MGraph* graph);//聲明清空?qǐng)D函數(shù)int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);//聲明添加邊函數(shù)int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);//聲明移除邊函數(shù)int MGraph_GetEdge(MGraph* graph, int v1, int v2);//聲明獲取邊函數(shù)int MGraph_TD(MGraph* graph, int v);//聲明以一個(gè)數(shù)作為行與列檢測(cè)不等于0的值的數(shù)量函數(shù)int MGraph_VertexCount(MGraph* graph);//聲明獲取頂點(diǎn)數(shù)量函數(shù)int MGraph_EdgeCount(MGraph* graph);//聲明獲取邊數(shù)量函數(shù)void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc);//聲明void MGraph_BFS(MGraph* graph, int v, MGraph_Printf* pFunc);//聲明void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc);//聲明#endifMGraph.c
#include <malloc.h> #include <stdio.h> #include "MGraph.h" #include "LinkQueue.h"typedef struct _tag_MGraph//定義實(shí)際使用圖類型 {int count;//數(shù)量MVertex** v;//指向頂點(diǎn)指針的指針變量int** matrix;//指向整型指針的指針變量 } TMGraph;//遞歸遍歷矩陣函數(shù) static void recursive_dfs(TMGraph* graph, int v, int visited[], MGraph_Printf* pFunc) {int i = 0;pFunc(graph->v[v]);visited[v] = 1;printf(", ");for(i=0; i<graph->count; i++){if( (graph->matrix[v][i] != 0) && !visited[i] ){recursive_dfs(graph, i, visited, pFunc);}} } //用隊(duì)列遍歷矩陣 static void bfs(TMGraph* graph, int v, int visited[], MGraph_Printf* pFunc) {LinkQueue* queue = LinkQueue_Create();//創(chuàng)建隊(duì)列if( queue != NULL )//創(chuàng)建成功{LinkQueue_Append(queue, graph->v + v);//將頂點(diǎn)信息存進(jìn)隊(duì)列visited[v] = 1;//將對(duì)應(yīng)行記錄為已查看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( (graph->matrix[v][i] != 0) && !visited[i] ){LinkQueue_Append(queue, graph->v + i);visited[i] = 1;}}}}LinkQueue_Destroy(queue); }MGraph* MGraph_Create(MVertex** v, int n) // 定義創(chuàng)建圖函數(shù) {TMGraph* ret = NULL;if( (v != NULL ) && (n > 0) ){ret = (TMGraph*)malloc(sizeof(TMGraph));//新建圖if( ret != NULL )//新建成功{int* p = NULL;ret->count = n;//設(shè)置數(shù)量ret->v = (MVertex**)malloc(sizeof(MVertex*) * n);//創(chuàng)建n個(gè)頂點(diǎn)指針類型的空間,v指向第一個(gè)ret->matrix = (int**)malloc(sizeof(int*) * n);//創(chuàng)建n個(gè)整型指針類型的空間,matrix指向第一個(gè)p = (int*)calloc(n * n, sizeof(int));//創(chuàng)建n*n個(gè)int 類型空間,p指向第一個(gè)if( (ret->v != NULL) && (ret->matrix != NULL) && (p != NULL) )//全部創(chuàng)建成功{int i = 0;for(i=0; i<n; i++){ret->v[i] = v[i];//將傳來的頂點(diǎn)信息給新建的圖中的頂點(diǎn)賦值ret->matrix[i] = p + i * n;//將新建圖中的矩陣指向p創(chuàng)建的地址(0,6,12,18,24,30)}}else//如果創(chuàng)建失敗,將申請(qǐng)的空間全部釋放{free(p);free(ret->matrix);free(ret->v);free(ret);ret = NULL;//返回空}}}return ret; }void MGraph_Destroy(MGraph* graph) //定義銷毀圖函數(shù) {TMGraph* tGraph = (TMGraph*)graph;//取得圖if( tGraph != NULL )//圖不為空,將空間全部釋放{free(tGraph->v);free(tGraph->matrix[0]);free(tGraph->matrix);free(tGraph);} }void MGraph_Clear(MGraph* graph) // 定義清空?qǐng)D函數(shù) {TMGraph* tGraph = (TMGraph*)graph;//取得圖if( tGraph != NULL )//圖不為空{int i = 0;int j = 0;for(i=0; i<tGraph->count; i++){for(j=0; j<tGraph->count; j++){tGraph->matrix[i][j] = 0;//將矩陣數(shù)值全設(shè)0}}} }int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w) // 定義添加邊函數(shù) {TMGraph* tGraph = (TMGraph*)graph;//取得圖int ret = (tGraph != NULL);//判斷是否為空ret = ret && (0 <= v1) && (v1 < tGraph->count);//判斷行數(shù)是否正常ret = ret && (0 <= v2) && (v2 < tGraph->count);//判斷列數(shù)是否正常ret = ret && (0 <= w);//判斷添加的值是否大于等于0if( ret )//條件成功{tGraph->matrix[v1][v2] = w;//將對(duì)應(yīng)行列值修改}return ret;//返回是否成功 }int MGraph_RemoveEdge(MGraph* graph, int v1, int v2) // 定義移除邊函數(shù) {int ret = MGraph_GetEdge(graph, v1, v2);//獲取移除的值if( ret != 0 )//圖不為空{((TMGraph*)graph)->matrix[v1][v2] = 0;//將對(duì)應(yīng)行列值重置0}return ret;//返回移除值 }int MGraph_GetEdge(MGraph* graph, int v1, int v2) // 定義獲取邊函數(shù) {TMGraph* tGraph = (TMGraph*)graph;//獲取圖int condition = (tGraph != NULL);//判斷圖不為空int ret = 0;condition = condition && (0 <= v1) && (v1 < tGraph->count);//判斷行是否正常condition = condition && (0 <= v2) && (v2 < tGraph->count);//判斷列是否正常if( condition ){ret = tGraph->matrix[v1][v2];//獲取對(duì)應(yīng)行列的值}return ret;//返回對(duì)應(yīng)值 }int MGraph_TD(MGraph* graph, int v) // 定義以一個(gè)數(shù)作為行與列檢測(cè)不等于0的值的數(shù)量函數(shù) {TMGraph* tGraph = (TMGraph*)graph;//取得圖int condition = (tGraph != NULL);//判斷圖不為空int ret = 0;condition = condition && (0 <= v) && (v < tGraph->count);//判斷v是否在范圍內(nèi)if( condition ){int i = 0;for(i=0; i<tGraph->count; i++)//如果一個(gè)位置的數(shù)值有效在行列交叉處會(huì)增加兩次{if( tGraph->matrix[v][i] != 0 )//如果以v作為行數(shù)將對(duì)應(yīng)行列的值不等于0{ret++;//數(shù)量增加}if( tGraph->matrix[i][v] != 0 )//如果以v作為列數(shù)將對(duì)應(yīng)行列的值不等于0{ret++;//數(shù)量增加}}}return ret;//返回總數(shù) }int MGraph_VertexCount(MGraph* graph) //定義獲取頂點(diǎn)數(shù)量 {TMGraph* tGraph = (TMGraph*)graph;int ret = 0;if( tGraph != NULL ){ret = tGraph->count;//取得數(shù)量}return ret; }int MGraph_EdgeCount(MGraph* graph) //定義獲取邊數(shù)函數(shù) {TMGraph* tGraph = (TMGraph*)graph;int ret = 0;if( tGraph != NULL ){int i = 0;int j = 0;for(i=0; i<tGraph->count; i++){for(j=0; j<tGraph->count; j++){if( tGraph->matrix[i][j] != 0 )//如果不等于0{ret++;//數(shù)量增加}}}}return ret;//返回總數(shù) }//從v行開始遍歷矩陣,visited記錄查看過的行。輸出v行頂點(diǎn)信息,從v行i列開始,只要i列不等于0并且用i值作為行檢測(cè) //i值行沒有看過。就跳到i行查看,此時(shí)i作為新v行又從v行i列開始檢測(cè)。循環(huán)檢測(cè)完矩陣每個(gè)元素 void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc) {TMGraph* tGraph = (TMGraph*)graph;//取得圖int* visited = NULL;int condition = (tGraph != NULL);//圖不為空condition = condition && (0 <= v) && (v < tGraph->count);//v是否在范圍內(nèi)condition = condition && (pFunc != NULL);//函數(shù)指針不為空//判斷新申請(qǐng)的count個(gè)int類型是否成功condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);if( condition ){int i = 0;recursive_dfs(tGraph, v, visited, pFunc);//調(diào)用遞歸檢測(cè)for(i=0; i<tGraph->count; i++)//如果還有行沒遍歷的,再從該行開始遍歷{if( !visited[i] ){recursive_dfs(tGraph, i, visited, pFunc);}}printf("\n");}free(visited);//釋放用于記錄查看行狀態(tài)的空間 } //從v行開始遍歷,visited記錄查看過的行 //將v行對(duì)應(yīng)頂點(diǎn)信息存進(jìn)隊(duì)列,表示從該行開始遍歷,將v行記錄為已查看,輸出v行頂點(diǎn)信息 //然后從出隊(duì)列的行開始遍歷,如果v行i列不等于0并且將i作為行檢測(cè)是否查看過 //如果沒有將i作為要遍歷的行進(jìn)隊(duì)列,當(dāng)前v行檢測(cè)完,再從隊(duì)列取元素循環(huán)同樣操作 void MGraph_BFS(MGraph* graph, int v, MGraph_Printf* pFunc) {TMGraph* tGraph = (TMGraph*)graph;//取得圖int* visited = NULL;int condition = (tGraph != NULL);condition = condition && (0 <= v) && (v < tGraph->count);condition = condition && (pFunc != NULL);condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);if( condition ){int i = 0;bfs(tGraph, v, visited, pFunc);for(i=0; i<tGraph->count; i++)//如果還有行沒遍歷的,再從該行開始遍歷{if( !visited[i] ){bfs(tGraph, i, visited, pFunc);}}printf("\n");}free(visited);//釋放用于記錄查看行狀態(tài)的空間 } //將矩陣中不為0的數(shù)值,將其坐標(biāo)與數(shù)值輸出 void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc) // O(n*n) {TMGraph* tGraph = (TMGraph*)graph;//取得圖if( (tGraph != NULL) && (pFunc != NULL) )//圖與函數(shù)指針不為空{int i = 0;int j = 0;for(i=0; i<tGraph->count; i++)//輸出所有頂點(diǎn)信息{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 )//將矩陣中不等于0的坐標(biāo)與數(shù)據(jù)輸出{printf("<");pFunc(tGraph->v[i]);//輸出行printf(", ");pFunc(tGraph->v[j]);//輸出列printf(", %d", tGraph->matrix[i][j]);//輸出對(duì)應(yīng)數(shù)據(jù)printf(">");printf(" ");}}}printf("\n");} }main.c
#include <stdio.h> #include <stdlib.h> #include "MGraph.h"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);//輸出:A,B,E,C,F,DMGraph_BFS(graph, 0, print_data);//輸出:A,B,C,D,E,FMGraph_Destroy(graph);getchar();return 0; }分析:
匯編:
總結(jié)
以上是生活随笔為你收集整理的MGraph图(代码、分析、汇编)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: “阴山饶苦雾”下一句是什么
- 下一篇: AAC ADTS格式分析