图的表示法--邻接矩阵

基本思想

  1. 用一维数组存储顶点
  2. 用二维数组存储边
    设图A = (V, E) 是一个有n个顶点的图,图的邻接矩阵为Edge[n][n],图的邻接矩阵为 Edge[n][n],则:
Edge[i][j] =   w,w>0,i和j连接
			   0,i==j或i和j不连接
注:w为权值,当不需要权值时,取w为1表示结点间连接。

图的表示法--邻接矩阵_第1张图片

图的表示法--邻接矩阵_第2张图片

邻接矩阵法简介

邻接矩阵法的头结点

  1. 记录顶点个数
  2. 记录与顶点相关的数据描述
  3. 记录描述边集的二维数组
typedef struct _tag_MGraph 
{
	int count;
	MVertex** v;
	int** matrix;
} TMGraph;

代码实现

LinkQueue.h

#pragma once
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);

MGraph.c

#pragma once

typedef void MGraph;
typedef void MVertex;
typedef void (MGraph_Printf)(MVertex*);

MGraph* MGraph_Create(MVertex** v, int n);

void MGraph_Destroy(MGraph* graph);

void MGraph_Clear(MGraph* graph);

int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w);

int MGraph_RemoveEdge(MGraph* graph, int v1, int v2);

int MGraph_GetEdge(MGraph* graph, int v1, int v2);
/*顶点的度*/
int MGraph_TD(MGraph* graph, int v);

int MGraph_VertexCount(MGraph* 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);

void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc);

LinkQueue.c

#include 
#include 
#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() // O(1)
{
    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) // O(n)
{
    LinkQueue_Clear(queue);
    free(queue);
}

void LinkQueue_Clear(LinkQueue* queue) // O(n)
{
    while (LinkQueue_Length(queue) > 0)
    {
        LinkQueue_Retrieve(queue);
    }
}

int LinkQueue_Append(LinkQueue* queue, void* item) // O(1)
{
    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) // O(1)
{
    TLinkQueue* sQueue = (TLinkQueue*)queue;
    TLinkQueueNode* node = NULL;
    void* ret = NULL;

    if ((sQueue != NULL) && (sQueue->length > 0))
    {
        node = sQueue->front;

        sQueue->front = node->next;

        ret = node->item;

        free(node);

        sQueue->length--;

        if (sQueue->length == 0)
        {
            sQueue->front = NULL;
            sQueue->rear = NULL;
        }
    }

    return ret;
}

void* LinkQueue_Header(LinkQueue* queue) // O(1)
{
    TLinkQueue* sQueue = (TLinkQueue*)queue;
    void* ret = NULL;

    if ((sQueue != NULL) && (sQueue->length > 0))
    {
        ret = sQueue->front->item;
    }

    return ret;
}

int LinkQueue_Length(LinkQueue* queue) // O(1)
{
    TLinkQueue* sQueue = (TLinkQueue*)queue;
    int ret = -1;

    if (sQueue != NULL)
    {
        ret = sQueue->length;
    }

    return ret;
}

MGraph.c

#include "MGraph.h"
#include 
#include 
#include "LinkQueue.h"

//邻接矩阵法
typedef struct _tag_MGraph 
{
	int count;//顶点个数
	MVertex** v;//顶点相关的数据
	int** matrix;//边集的二维数组
} TMGraph;

MGraph* MGraph_Create(MVertex** v, int n)
{
	TMGraph* ret = NULL;
	int* p =NULL;
	int i = 0;
	if (NULL == v || n <=0)
	{
		return ret;
	}
	ret = (TMGraph*)malloc(sizeof(TMGraph));
	if (NULL == ret) 
	{
		return ret;
	}
	ret->count = n;
	ret->v = (MVertex**)malloc(sizeof(MVertex*)*n);
	ret->matrix = (int**)malloc(sizeof(int*)*n);
	p = (int**)calloc(n * n, sizeof(int));
	if (p!=NULL && (ret->v!=NULL) && (ret->matrix!=NULL))
	{
		for (i = 0; i < n;++i) 
		{
			ret->v[i] = v[i];
			ret->matrix[i] = p + i * n;
		}
	}
	else 
	{
		free(p);
		free(ret->v);
		free(ret->matrix);
		free(ret);
		ret = NULL;
	}

	return ret;
}

void MGraph_Destroy(MGraph* graph)
{
	TMGraph* tGraph = (TMGraph*)graph;
	if (tGraph!=NULL) 
	{
		free(tGraph->v);
		free(tGraph->matrix[0]);
		free(tGraph->matrix);
		free(tGraph);
	}
}

void MGraph_Clear(MGraph* graph)
{
	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;
			}
		}
	}
}

int MGraph_AddEdge(MGraph* graph, int v1, int v2, int w)
{
	TMGraph* tGraph = (TMGraph*)graph;
	int ret = (tGraph != NULL);
	ret = ret && (0<=v1 && v1<tGraph->count);
	ret = ret && (0<=v2 && v2<tGraph->count);
	ret = ret && (0<=w);
	if (ret) 
	{
		tGraph->matrix[v1][v2] = w;
	}
	return ret;
}

int MGraph_RemoveEdge(MGraph* graph, int v1, int v2) 
{
	int ret = MGraph_GetEdge(graph, v1, v2);
	if (ret != 0) 
	{
		((TMGraph*)graph)->matrix[v1][v2] = 0;
	}
	return ret;
}

int MGraph_GetEdge(MGraph* graph, int v1, int v2) 
{
	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];
	}
	return ret;
}

int MGraph_TD(MGraph* graph, int v) 
{
	TMGraph* tGraph = (TMGraph*)graph;
	int condition = (tGraph != NULL);
	condition = condition && (0<=v && v<tGraph->count);

	int ret = 0;
	int i = 0;
	if (condition) 
	{
		for (i = 0; i < tGraph->count;++i) 
		{
			if (tGraph->matrix[i][v] !=0)
			{
				++ret;
			}
			if (tGraph->matrix[v][i]!=0) 
			{
				++ret;
			}
		}
	}
	return ret;
}

int MGraph_VertexCount(MGraph* graph) 
{
	TMGraph* tGraph = (TMGraph*)graph;
	int ret = 0;
	if (NULL != tGraph) 
	{
		ret = tGraph->count;
	}
	return ret;
}

int MGraph_EdgeCount(MGraph* graph) 
{
	TMGraph* tGraph = (TMGraph*)graph;
	int ret = 0, i = 0, j = 0;
	if (tGraph!=NULL) 
	{
		for (i = 0; i < tGraph->count;++i) 
		{
			for (j = 0; j < tGraph->count;++j) 
			{
				if (tGraph->matrix[i][j]!=0)
				{
					ret++;
				}
			}
		}
	}
	return ret;
}

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);
		}
	}
}

void MGraph_DFS(MGraph* graph, int v, MGraph_Printf* pFunc) 
{
	int i = 0;
	TMGraph* tGraph = (TMGraph*)graph;
	int* visited = NULL;
	int condition = (v>=0 && v<tGraph->count);
	condition = condition && tGraph != NULL;
	condition = condition && pFunc != NULL;
	condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);
	
	if (condition) {
		recursive_dfs(tGraph, v, visited, pFunc);
		for (i = 0; i < tGraph->count; ++i) {
			if (!visited[i]) {
				recursive_dfs(tGraph, i, visited, pFunc);
			}
		}
		printf("\n");
	}
	free(visited);
}
static void recursive_bfs(TMGraph* graph, int v, int* visited, MGraph_Printf* pFunc) 
{
	int i = 0;
	LinkQueue* queue = LinkQueue_Create();
	if (queue != NULL) {
		LinkQueue_Append(queue, graph->v + v);
		visited[v] = 1;
		while (LinkQueue_Length(queue) > 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);
}

void MGraph_BFS(MGraph* graph, int v, MGraph_Printf* pFunc) 
{
	int i = 0;
	TMGraph* tGraph = (TMGraph*)graph;
	int* visited = NULL;
	int condition = (v >= 0 && v < tGraph->count);
	condition = condition && tGraph != NULL;
	condition = condition && pFunc != NULL;
	condition = condition && ((visited = (int*)calloc(tGraph->count, sizeof(int))) != NULL);

	if (condition) {
		recursive_bfs(tGraph, v, visited, pFunc);
		for (i = 0; i < tGraph->count; ++i) {
			if (!visited[i]) {
				recursive_bfs(tGraph, i, visited, pFunc);
			}
		}
		printf("\n");
	}
	free(visited);
}

void MGraph_Display(MGraph* graph, MGraph_Printf* pFunc) 
{
	TMGraph* tGraph = (TMGraph*)graph;
	if (tGraph!=NULL && pFunc!=NULL) 
	{
		int i = 0, 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");
	}
}

main.c

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 
#include 
#include 
#include 
#include 
#include "MGraph.h"

void print_data(MVertex* v) 
{
	printf("%s", (char*)v);
}

int main(void)
{
	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);
	MGraph_BFS(graph, 0, print_data);
	MGraph_Destroy(graph);


	system("pause");
	return EXIT_SUCCESS;
}

运行结果:

0:A 1:B 2:C 3:D 4:E 5:F
       
A,B,E,C,F,D,
A,B,C,D,E,F,

你可能感兴趣的:(数据结构)