图的深度搜索类似于树的先序遍历,稍微修改即可利用递归实现。
图的广度搜索类似于树的层序遍历,根据数据出入的特性,可以采用队列来实现。队列不使用容器,而采用之前自己写过的队列稍加修改后来使用。
所以文件一共有五个,包括图头文件,图实现文件,队列头文件,队列实现文件,主函数文件。
队列头文件:
#ifndef MYQUEUE_H_
#define MYQUEUE_H_
#define QUEUEMAXSIZE 10 //队列数组容量 下标从0-99
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
struct MyQueue;
typedef struct MyQueue * Queue;
typedef int ElementType;
int MyAdd(int number); // 内联函数,用于对组下标越界后的处理,达到下标循环的目的
Queue InitQueue(void);//构造一个空队列
bool QueueEmpty(Queue Q);//队列Q是否为空,空返回True
void DestoryQueue(Queue Q); //从内存中销毁(删除)队列Q
void ClearQueue(Queue Q); //清空队列Q
int QueueLength(Queue Q);//返回队列中元素个数
ElementType GetHead(Queue Q);//返回队列头元素
void OutQueue(Queue Q);//出队
void EnQueue(ElementType E, Queue Q);//入队,从队尾插入
#endif
队列实现文件:
#include "MyQueue.h"
struct MyQueue
{
ElementType * Array; //数组指针
int front; //队头下标
int rear; //队尾下标
int maxsize; //数组容量,用以判断数组是否满
int length; //队长,即队中元素个数
};
int MyAdd(int number) //某种意义上类似于自定义++运算符
{
if (number == QUEUEMAXSIZE - 1)
return 0;
else
return number + 1;
}
Queue InitQueue(void)
{
Queue Q;
Q = (Queue)malloc(sizeof(struct MyQueue));
if (Q == NULL)
printf("Out Of Space!\n");
Q->Array = (ElementType *)malloc(sizeof(ElementType) * QUEUEMAXSIZE);
if (Q->Array == NULL)
printf("Out Of Space!\n");
Q->front = 0;
Q->rear = 0;
Q->length = 0;
Q->maxsize = QUEUEMAXSIZE;
return Q;
}
bool QueueEmpty(Queue Q)
{
if (Q->length == 0)
return true;
return false;
}
void DestoryQueue(Queue Q)
{
free(Q->Array);
free(Q);
}
void ClearQueue(Queue Q)
{
Q->front = 0;
Q->rear = 0;
Q->length = 0;
}
int QueueLength(Queue Q)
{
return Q->length;
}
ElementType GetHead(Queue Q)
{
if (QueueEmpty(Q)){
printf("Queue is empty!\n");
return 0; //因为函数必须要有返回值,故返回零
}
return Q->Array[Q->front];
}
void OutQueue(Queue Q)
{
if (QueueEmpty(Q))
printf("Queue is empty!\n");
else{
Q->front = MyAdd(Q->front);
Q->length--;
}
}
void EnQueue(ElementType E, Queue Q)
{
if (Q->length == Q->maxsize)
printf("Queue is full!\n");
else{
Q->Array[Q->rear] = E;
Q->rear = MyAdd(Q->rear);
Q->length++;
}
}
图头文件:
#ifndef ADJACENCYMATRIX_H
#define ADJACENCYMATRIX_H
#define FLOWOVER -1
#define MAX_VERTEX_NUM 8
struct AdjacencyMatrix;//邻接表
struct VecNodeOfAdjacencyMatrix;//顶点列表头结点
struct ArcNodeOfAdjacencyMatrix;//图的边
typedef struct AdjacencyMatrix AdjMatrix;
typedef struct VecNodeOfAdjacencyMatrix VecNode;
typedef struct ArcNodeOfAdjacencyMatrix * AdjNode;
typedef char ElemType;
struct VecNodeOfAdjacencyMatrix
{
ElemType elem;//该点的数据域
int degree;//该点的度
AdjNode next;//指向下一条边的指针
};
struct AdjacencyMatrix
{
VecNode list[MAX_VERTEX_NUM];//顶点列表
int vexnum;//图的总节点数
int arcnum;//图的总边数
};
struct ArcNodeOfAdjacencyMatrix
{
int number;//该边的弧头
int weight;//边的权重
AdjNode next;//指向下一条边的指针
};
void CreatAdjMatrix(AdjMatrix & A);//初始化一个图
bool AddVex(AdjMatrix & A, ElemType E, int D);//输入图,节点值,节点度,添加节点,成功返回true
static AdjNode tailOfList(AdjNode N);//若顶点节点后面有边节点,输入该边节点地址,返回横向链最后一条边的地址
bool AddArc(AdjMatrix & A, int tailOfArc, int headOfArc, int W);//输入图,弧头尾编号,弧权重,添加弧,成功返回true
void PrintAdjMatrix(AdjMatrix A);//输入图,打印出图
void DepthFirstSearch(AdjMatrix A, int v);//图的深度优先搜索
static void DFS(AdjMatrix A, int v);
void BreadthFirstSearch(AdjMatrix A, int v);//图的广度优先搜索
#endif
图实现文件:
#include <stdlib.h>
#include <stdio.h>
#include "AdjacencyMatrix.h"
#include "MyQueue.h"
static int visited[MAX_VERTEX_NUM];
void CreatAdjMatrix(AdjMatrix & A)
{
for (int i = 0; i < MAX_VERTEX_NUM; i++){
A.list[i].elem = -1;
A.list[i].degree = 0;
A.list[i].next = NULL;
A.vexnum = 0;
A.arcnum = 0;
}
}
bool AddVex(AdjMatrix & A, ElemType E, int D)
{
A.list[A.vexnum].elem = E;
A.list[A.vexnum].degree = D;
A.list[A.vexnum].next = NULL;
A.vexnum++;
return true;
}
static AdjNode tailOfList(AdjNode N)
{
while (N->next != NULL){
N = N->next;
}
return N;
}
bool AddArc(AdjMatrix & A, int tailOfArc, int headOfArc, int W)
{
if (tailOfArc < A.vexnum && headOfArc < A.vexnum){
if (A.list[tailOfArc].next == NULL){
A.list[tailOfArc].next = (AdjNode)malloc(sizeof(struct ArcNodeOfAdjacencyMatrix));
if (A.list[tailOfArc].next == NULL){
exit(FLOWOVER);
}
A.list[tailOfArc].next->next = NULL;
A.list[tailOfArc].next->number = headOfArc;
A.list[tailOfArc].next->weight = W;
}
else{
AdjNode tempNode = tailOfList(A.list[tailOfArc].next);
tempNode->next = (AdjNode)malloc(sizeof(struct ArcNodeOfAdjacencyMatrix));
if (tempNode->next == NULL){
exit(FLOWOVER);
}
tempNode->next->next = NULL;
tempNode->next->number = headOfArc;
tempNode->next->weight = W;
}
A.arcnum++;
return true;
}
else{
printf("请先输入节点!\n");
return false;
}
}
void PrintAdjMatrix(AdjMatrix A)
{
}
void DepthFirstSearch(AdjMatrix A, int v)
{
int visited[MAX_VERTEX_NUM];
for (int i = 0; i < MAX_VERTEX_NUM; i++){
visited[i] = 0;
}
if (visited[v] == 0)
DFS(A, v);
}
static void DFS(AdjMatrix A, int v)
{
printf("%c ", A.list[v].elem);
visited[v] = 1;
AdjNode tempNode = A.list[v].next;
while (tempNode != NULL){
if (visited[tempNode->number] == 0){
DFS(A, tempNode->number);
}
tempNode = tempNode->next;
}
}
void BreadthFirstSearch(AdjMatrix A, int v)
{
int visited[MAX_VERTEX_NUM];
int u;
int flag = 0;//用于标记是否所有点都被访问过了
for (int i = 0; i < MAX_VERTEX_NUM; i++){
visited[i] = 0;
}
Queue Q;
Q = InitQueue();
if (visited[v] == 0){
printf("%c ", A.list[v].elem);
visited[v] = 1;
flag++;
u = v;
EnQueue(v, Q);
while (flag != A.vexnum){
AdjNode tempNode = A.list[u].next;
while (tempNode != NULL){
if (visited[tempNode->number] == 0){
visited[tempNode->number] = 1;
flag++;
printf("%c ", A.list[tempNode->number].elem);
EnQueue(tempNode->number, Q);
}
tempNode = tempNode->next;
}
u = GetHead(Q);
OutQueue(Q);
}
}
}
主函数文件:
#include <stdlib.h>
#include <stdio.h>
#include "AdjacencyMatrix.h"
int main()
{
AdjMatrix testAdj;
CreatAdjMatrix(testAdj);
AddVex(testAdj, 'a', 2);
AddVex(testAdj, 'b', 3);
AddVex(testAdj, 'c', 3);
AddVex(testAdj, 'd', 4);
AddVex(testAdj, 'e', 2);
AddVex(testAdj, 'f', 2);
AddArc(testAdj, 0, 2, 1);
AddArc(testAdj, 0, 1, 1);
AddArc(testAdj, 1, 0, 1);
AddArc(testAdj, 1, 2, 1);
AddArc(testAdj, 1, 3, 1);
AddArc(testAdj, 2, 0, 1);
AddArc(testAdj, 2, 1, 1);
AddArc(testAdj, 2, 3, 1);
AddArc(testAdj, 3, 1, 1);
AddArc(testAdj, 3, 2, 1);
AddArc(testAdj, 3, 4, 1);
AddArc(testAdj, 3, 5, 1);
AddArc(testAdj, 4, 3, 1);
AddArc(testAdj, 4, 5, 1);
AddArc(testAdj, 5, 3, 1);
AddArc(testAdj, 5, 4, 1);
printf("深度优先搜索:");
DepthFirstSearch(testAdj, 0);
printf("\n");
printf("广度优先搜索:");
BreadthFirstSearch(testAdj, 0);
printf("\n");
system("pause");
return 0;
}