当前位置 博文首页 > Inmaturity_7的博客:408计算机考研--数据结构--图的学习(C语言
特点:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MaxVertexNum 100 //顶点数目的最大值
#define Max 0x7FFFFFFF //int最大数
typedef char VertexType; //顶点的数据类型
typedef int EdgeType; //带权图中边上权值的数据类型
typedef struct{
VertexType Vex[MaxVertexNum]; //顶点表
EdgeType Edge[MaxVertexNum][MaxVertexNum];//邻接矩阵,边表
int vexnum,arcnum;//图的当前顶点数和弧数
}MGragh;
//链表
typedef struct LinkNode{
int val;//数据域
struct LinkNode *next;//指针域
}LinkNode,*LinkedList;
//链式存储队列
typedef struct LinkedQueue{
LinkedList front,rear;
}LinkedQueue;
//初始化队列
void Init_LinkedQueue(LinkedQueue &q){
q.front=q.rear=(LinkedList)malloc(sizeof(LinkNode));//建立队头和队尾
q.front->next=NULL;
}
//判队空
bool is_Empty(LinkedQueue &q){
if(q.front==q.rear){
return true;
}
return false;
}
//入队
void EnQueue(LinkedQueue &q,int x){
LinkedList newNode=(LinkedList)malloc(sizeof(LinkNode));//新结点
newNode->val=x;
newNode->next=NULL;
//插入新结点
q.rear->next=newNode;
q.rear=newNode;
return;
}
//出队
bool DeQueue(LinkedQueue &q,int &x){
if(is_Empty(q)){
return false;
}
//获取被删结点
LinkedList p=q.front->next;
x=p->val;
//删除结点
q.front->next=p->next;
if(q.rear==p){
q.rear=q.front;
}
free(p);
return true;
}
//找出图G的x顶点的第一个邻接点
//若有则返回顶点号。若没有返回-1
int FirstNeighbor(MGragh G,int x){
if(x<0||x>=G.vexnum){//判断图是否存在以及查找顶点是否在表其中,不在的话直接返回-1
return -1;
}
for(int i=0;i<G.vexnum;i++){
if(G.Edge[x][i]==1){
return i;//查找到第一个邻接点
}
}
return -1;
}
//找出图G的x顶点的y的下一个邻接点
//若有则返回顶点号。若没有返回-1
int NextNeighbor(MGragh G,int x,int y){
if(x<0||x>=G.vexnum||y<0||y>=G.vexnum){//判断图是否存在以及查找顶点是否在表其中,不在的话直接返回-1
return -1;
}
for(int i=y+1;i<G.vexnum;i++){
if(G.Edge[x][i]==1){
return i;//查找y的下一个邻接点
}
}
return -1;
}
//深度优先遍历算法
void DFS(MGragh G,int v,bool* visited){
visited[v]=1;//将当前顶点标记为已访问
printf("%c->",G.Vex[v]);//打印该结点
for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
DFS(G,w,visited);
}
}
}
//对图进行深度优先遍历
void DFSTraverse(MGragh G,bool* visited){
for(int v=0;v<G.vexnum;v++){//从第一个结点开始遍历整个顶点表
if(!visited[v]){
DFS(G,v,visited);
}
}
printf("\n");
}
//广度优先遍历算法
void BFS(MGragh G,int v,bool* visited){
LinkedQueue q;
Init_LinkedQueue(q);//初始化队列
EnQueue(q,v);//初始顶点入队列
visited[v]=1;
printf("%c->",G.Vex[v]);//打印该结点
while(!is_Empty(q)){
DeQueue(q,v);//出队列
for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
EnQueue(q,w);
visited[w]=1;
printf("%c->",G.Vex[w]);//打印该结点
}
}
}
}
void BFSTraverse(MGragh G,bool* visited){
for(int v=0;v<G.vexnum;v++){//从第一个结点开始遍历整个顶点表
if(!visited[v]){
BFS(G,v,visited);
}
}
printf("\n");
}
int main(){
//测试图
MGragh mGragh={"ABCDEFGH",
{{0,1,0,0,1,0,0,0},
{1,0,0,0,0,1,0,0},
{0,0,0,1,0,1,1,0},
{0,0,1,0,0,0,1,1},
{1,0,0,0,0,0,0,0},
{0,1,1,0,0,0,1,0},
{0,0,1,1,0,1,0,1},
{0,0,0,1,0,0,1,0}},
8,
10};
bool visited[mGragh.vexnum];//定义访问顶点记录数组
memset(visited,0,sizeof(visited));
//DFS深度遍历算法
DFSTraverse(mGragh,visited);
memset(visited,0,sizeof(visited));
//BFS广度遍历算法
BFSTraverse(mGragh,visited);
//A->B->F->C->D->G->H->E->
//A->B->E->F->C->G->D->H->
}
特点:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxVertexNum 100 //顶点数目的最大值
typedef char VertexType;//顶点类型
typedef struct ArcNode{//边表结点
int adjvex;//该弧所指向的顶点的为止
struct ArcNode *next;//指向下一条弧的指针
//InfoType info; //网的边权值
}ArcNode;
typedef struct VNode{//顶点表结点
VertexType data;//顶点信息
ArcNode *first;//指向第一条依附该顶点的弧的指针
}VNode,AdjList[MaxVertexNum];
typedef struct{
AdjList vertices;//邻接表
int vexnum,arcnum;//图的顶点数和弧数
}ALGraph;//ALGraph是以邻接表存储的图类型
//链表
typedef struct LinkNode{
int val;//数据域
struct LinkNode *next;//指针域
}LinkNode,*LinkedList;
//链式存储队列
typedef struct LinkedQueue{
LinkedList front,rear;
}LinkedQueue;
//初始化队列
void Init_LinkedQueue(LinkedQueue &q){
q.front=q.rear=(LinkedList)malloc(sizeof(LinkNode));//建立队头和队尾
q.front->next=NULL;
}
//判队空
bool is_Empty(LinkedQueue &q){
if(q.front==q.rear){
return true;
}
return false;
}
//入队
void EnQueue(LinkedQueue &q,int x){
LinkedList newNode=(LinkedList)malloc(sizeof(LinkNode));//新结点
newNode->val=x;
newNode->next=NULL;
//插入新结点
q.rear->next=newNode;
q.rear=newNode;
return;
}
//出队
bool DeQueue(LinkedQueue &q,int &x){
if(is_Empty(q)){
return false;
}
//获取被删结点
LinkedList p=q.front->next;
x=p->val;
//删除结点
q.front->next=p->next;
if(q.rear==p){
q.rear=q.front;
}
free(p);
return true;
}
//找出图G的x顶点的第一个邻接点
//若有则返回顶点号。若没有返回-1
int FirstNeighbor(ALGraph G,int x){
if(x<0||x>=G.vexnum){//判断图是否存在以及查找顶点是否在表其中,不在的话直接返回-1
return -1;
}
ArcNode* arc=G.vertices[x].first;//获取该弧
return arc==NULL?-1:arc->adjvex;
}
//找出图G的x顶点的y的下一个邻接点
//若有则返回顶点号。若没有返回-1
int NextNeighbor(ALGraph G,int x,int y){
if(x<0||x>=G.vexnum||y<0||y>=G.vexnum){//判断图是否存在以及查找顶点是否在表其中,不在的话直接返回-1
return -1;
}
ArcNode* arc=G.vertices[x].first;//获取该弧
while(arc!=NULL&&arc->adjvex!=y){
arc=arc->next;
}
if(arc==NULL){
return -1;
}else{
return arc->next==NULL?-1:arc->next->adjvex;
}
}
//深度优先遍历算法
void DFS(ALGraph G,int v,bool* visited){
visited[v]=1;//将当前顶点标记为已访问
printf("%c->",G.vertices[v].data);//打印该结点
for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
DFS(G,w,visited);
}
}
}
//对图进行深度优先遍历
void DFSTraverse(ALGraph G,bool* visited){
for(int v=0;v<G.vexnum;v++){//从第一个结点开始遍历整个顶点表
if(!visited[v]){
DFS(G,v,visited);
}
}
printf("\n");
}
//广度优先遍历算法
void BFS(ALGraph G,int v,bool* visited){
LinkedQueue q;
Init_LinkedQueue(q);//初始化队列
EnQueue(q,v);//初始顶点入队列
visited[v]=1;
printf("%c->",G.vertices[v].data);//打印该结点
while(!is_Empty(q)){
DeQueue(q,v);//出队列
for(int w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v,w)){
if(!visited[w]){
EnQueue(q,w);
visited[w]=1;
printf("%c->",G.vertices[w].data);//打印该结点
}
}
}
}
void BFSTraverse(ALGraph G,bool* visited){
for(int v=0;v<G.vexnum;v++){//从第一个结点开始遍历整个顶点表
if(!visited[v]){
BFS(G,v,visited);
}
}
printf("\n");
}
int main(){
//初始化邻接表图
ALGraph g;
g.vexnum=8;
g.arcnum=10;
g.vertices[0].data='A';//结点A
ArcNode* a1=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[0].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[0].first->adjvex=1;
a1->adjvex=4;
a1->next=NULL;
g.vertices[0].first->next=a1;
g.vertices[1].data='B';//结点B
ArcNode* b1=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[1].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[1].first->adjvex=0;
b1->adjvex=5;
b1->next=NULL;
g.vertices[1].first->next=b1;
g.vertices[2].data='C';//结点C
ArcNode* c1=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode* c2=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[2].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[2].first->adjvex=3;
c1->adjvex=5;
c2->adjvex=6;
c1->next=c2;
c2->next=NULL;
g.vertices[2].first->next=c1;
g.vertices[3].data='D';//结点D
ArcNode* d1=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode* d2=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[3].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[3].first->adjvex=2;
d1->adjvex=6;
d2->adjvex=7;
d1->next=d2;
d2->next=NULL;
g.vertices[3].first->next=d1;
g.vertices[4].data='E';//结点E
g.vertices[4].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[4].first->adjvex=0;
g.vertices[4].first->next=NULL;
g.vertices[5].data='F';//结点F
ArcNode* f1=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode* f2=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[5].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[5].first->adjvex=1;
f1->adjvex=2;
f2->adjvex=6;
f1->next=f2;
f2->next=NULL;
g.vertices[5].first->next=f1;
g.vertices[6].data='G';//结点G
ArcNode* g1=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode* g2=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode* g3=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[6].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[6].first->adjvex=2;
g1->adjvex=3;
g2->adjvex=5;
g3->adjvex=7;
g1->next=g2;
g2->next=g3;
g3->next=NULL;
g.vertices[6].first->next=g1;
g.vertices[7].data='H';//结点H
ArcNode* h1=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[7].first=(ArcNode*)malloc(sizeof(ArcNode));
g.vertices[7].first->adjvex=3;
h1->adjvex=6;
h1->next=NULL;
g.vertices[7].first->next=h1;
bool visited[g.vexnum];//定义访问顶点记录数组
memset(visited,0,sizeof(visited));
//DFS深度遍历算法
DFSTraverse(g,visited);
memset(visited,0,sizeof(visited));
//BFS广度遍历算法
BFSTraverse(g,visited);
//A->B->F->C->D->G->H->E->
//A->B->E->F->C->G->D->H->
}
? 十字链表是有向图的一种存储结构。
? 弧节点:tailvex(记录弧尾在图中的位置)、headvex(记录弧头在图中的位置)、hlink(指向弧头相同下一条弧)、tlink(指向弧尾相同的下一条弧)、info(指向该弧的相关信息)
? 顶点结点:data(存储顶点相关的数据信息)、firstin(指向该顶点为弧头的第一个弧结点)、firstout(指向该顶点为弧尾的第一个弧结点)
#include<stdio.h>
#define MaxVertexNum 100 //图中顶点数目的最大值
typedef struct ArcNode{//弧结点
int tailvex;//弧尾
int headvex;//弧头
ArcNode hlink*;//指向弧头相同的下一条弧
ArcNode tlink*;//指向弧尾相同的下一条弧
int info;//弧的相关信息
}ArcNode;
typedef struct VertexNode{//顶点
int data;// 存储顶点相关的数据信息
ArcNode firstin*;//指向该顶点为弧头的第一个弧结点
ArcNode firstout*;//指向该顶点为弧尾的第一个弧结点
}VertexNode,CrossList[MaxVertexNum];
typedef struct{
CrossList crossList;//十字链表
int vexnum,arcnum;//图的顶点数和弧数
}ALGraph;//ALGraph是以十字链表存储的图类型
邻接多重表是无向图的另一种存储结构。
? 弧节点:mark(标志域,可以标记该条边是否被搜索过);ivex(记录弧尾在图中的位置)、ilink(指向下一条依附于顶点ivex的边)、jvex(记录弧头在图中的位置)、jlink(指向下一条依附于点jvex的边)、info(为指向和边的各种信息的指针域)
? 顶点结点:data(存储顶点相关的数据信息)、firstedge(指示第一条依附于该顶点的边)。
#include<stdio.h>
#define MaxVertexNum 100 //图中顶点数目的最大值
typedef struct ArcNode{//弧结点
bool mark;//弧尾
int ivex;//弧头
ArcNode ilink*;//指向弧头相同的下一条弧
int jvex;//弧尾
ArcNode jlink*;//指向弧尾相同的下一条弧
int info;//弧的相关信息
}ArcNode;
typedef struct VertexNode{//顶点
int data;// 存储顶点相关的数据信息
ArcNode firstedge*;//指向该顶点为弧头的第一个弧结点
}VertexNode,MultiList[MaxVertexNum];
typedef struct{
MultiList multiList;//邻接多重表
int vexnum,arcnum;//图的顶点数和弧数
}ALGraph;//ALGraph是以邻接多重表存储的图类型
cs