图的创建
图的邻接矩阵存储
#define INFINITY 65535
/*邻接矩阵表示图*/
/*图结点的定义*/
typedef int WeightType; //抽象一下,WeightType可取各种类型,DataType什么也是一样的
typedef struct GNode *PtrToNode;
struct GNode{
int Nv;//顶点数
int Ne;//边数
WeightType G[maxVertexNum][MaxVertexNum]; //邻接矩阵,里面放权重Weight
DataType Data[maxVertexNum];//存顶点的数据 不是必须有
};
typedef PtrToNode MGraph;
/*初始化,无边*/
typedef int Vertex;
MGraph craeatGraph(int VertexNum) //返回一个图嗷!!!
{
MGraph Graph;
Vertex v,w;
Graph=(MGraph)malloc(sizeof(struct GNode));
Graph->Nv=VertexNum;
Graph->Ne=0;//还没有边
for(v=0;v<Graph->Nv;v++)
{
for(w=0;w<Graph->Nv;w++)
{
Graph->G[v][w]=INFINITY;//define INFINITY 65535(无限大)
}
}
return Graph;
}
/*插入边*/
typedef struct ENode *PtrToNode;//先定义一个边结构
struct ENode{
Vertex v1,v2;//有向边 <v1,v2>
WeightType weight;//权重
};
typedef PtrToNode Edge;
void insertEdge(MGraph Graph,Edge E)
{
Graph->G[E->v1][E->v2]=E->weight;
/*如果是有向图*/
Graph->G[E->v2][E->v1]=E->weight;
}
void BuildGraph0()
{
//此处待补充
}
/*完整建图*/
/*输入格式
Nv Ne
V1 V2 Weight */
/*不用上面的铺垫(工程性比较强....)的建图*/
int G[maxv][maxv];
int Nv,Ne;
void BuildGraph()
{
int i,j,Nv,Ne,v1,v2,weight;
scanf("%d",&Nv);
for(i=0;i<Nv;i++)
{
for(j=0;j<Nv;j++)
G[i][j]=0;
}
scanf("%d",&Ne);
for(i=0;i<Ne;i++)
{
scanf("%d%d%d",&v1,&v2,&weight);
G[v1][v2]=weight;
G[v2][v1]=weight;
}
}
图的邻接表存储
有点吐血
//邻接表实现 G[N]为指针数组,对应矩阵每行一个链表,只存非0元素
typedef struct GNode *PtrToNode;
struct GNode{
int Nv;//顶点数
int Ne;//边数
AdjList G;//邻接表,数组
};
typedef PtrToNode LGraph;
//表!
typedef struct Vnode{
PtrToNodeVNode FirstEdge;//总是指向链表的第一条边
//DataType data;有结点的数据
}AdjList[MaxVertexNum];
typedef struct AdjVNode *PtrToNodeVNode;//链表
struct AdjVNode{
Vertex AdjV;//邻接点下标
WeightType Weight;//边权重
PtrToAdjVNode next;//指针域
};
typedef int Vertex;
LGraph CreatGraph(int Vertexnum)
{
Vertex v,w;
LGraph Graph;
Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Nv=Vertexnum;
Graph->Ne=0;
for(v=0;v<Vertexnum;v++)
{
Graph->G[v].FirstEdge=NULL;
}
return Graph;
}
struct node2{
Vertex v1,v2;
int weight;
};
typedef struct node2 Edge;
void insert(LGraph Graph,Edge E)
{
PtrToAdjVNode newNode;//先建立邻接点
Newnode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
Newnode->AdjV=E->v2;
Newnode->Weight=E->weight;
//将v2插入v1表头
Newnode->next=Graph->G[E->v1].FirstEdge;
Graph->G[E->v1].FirstEdge=Newnode;
//如果是无向图
PtrToAdjVNode newNode;//先建立邻接点
Newnode=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
Newnode->AdjV=E->v1;
Newnode->Weight=E->weight;
//将v1插入v2表头
Newnode->next=Graph->G[E->v2].FirstEdge;
Graph->G[E->v2].FirstEdge=Newnode;
}
最终…
void BuildGraph(){
int i;
int v1,v2,w;
AdjList NewNode;
scanf("%d",&Nv);
for(i=0;i<Nv;i++){
Graph[i] = (AdjList)malloc(sizeof(struct AdjVNode));
Graph[i]->adjv = i;
Graph[i]->next = NULL;
}
scanf("%d",&Ne);
for(i=0;i<Ne;i++){
scanf("%d %d %d",&v1,&v2,&w);
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
NewNode->adjv = v1;
NewNode->weight = w;
NewNode->next = Graph[v2]->next;
Graph[v2]->next = NewNode;
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
NewNode->adjv = v2;
NewNode->weight = w;
NewNode->next = Graph[v1]->next;
Graph[v1]->next = NewNode;
}
}
void print(){
AdjList tmp;
int i;
for(i=0;i<Nv;i++){
tmp = Graph[i];
while(tmp){
printf("%d ",tmp->adjv);
tmp = tmp->next;
}
printf("\n");
}
}
简化!!!比前面的简单太多
注意此处的图是一个结点类型(指向结构体)的指针数组,下标代表序号
#include<stdio.h>
#include<stdlib.h>
#define MaxVertexNum 100
typedef struct AdjVNode *AdjList;
struct AdjVNode{
int weight; // 权值
int adjv; // 下标
AdjList next; // 其后一个
};
AdjList Graph[MaxVertexNum];
int Ne,Nv;
// 建图
void BuildGraph(){
int i;
int v1,v2,w;
AdjList NewNode;
scanf("%d",&Nv);
for(i=0;i<Nv;i++){
Graph[i] = (AdjList)malloc(sizeof(struct AdjVNode));
Graph[i]->adjv = i;
Graph[i]->next = NULL;
}
scanf("%d",&Ne);
for(i=0;i<Ne;i++){
scanf("%d %d %d",&v1,&v2,&w);
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
NewNode->adjv = v1;
NewNode->weight = w;
NewNode->next = Graph[v2]->next;
Graph[v2]->next = NewNode;
//-------分割线------------
NewNode = (AdjList)malloc(sizeof(struct AdjVNode));
NewNode->adjv = v2;
NewNode->weight = w;
NewNode->next = Graph[v1]->next;
Graph[v1]->next = NewNode;
}
}
void print(){
AdjList tmp;
int i;
for(i=0;i<Nv;i++){
tmp = Graph[i];
while(tmp){
printf("%d ",tmp->adjv);
tmp = tmp->next;
}
printf("\n");
}
}
int main(){
BuildGraph();
print();
return 0;
}
图的遍历
DFS
为了好理解,先用伪代码来表示一下
void DFS(Vertex v)
{
visited[v]=true;
for(v的每个邻接点w)
{
if(!visited[w])
DFS(w);
}
}
BFS
类似于树的层序遍历,需要新建一个队列
void BFS(Vertex v)
{
queue<Vertex> q;
visited[v]=true;
q.push(v);
while(!q.empty())
{
v=q.front();q.pop();
for(v的每个邻接点w)
{
if(!visited[w])
{
visited[w]=true;
q.push(w);
}
}
}
}
void BFS(int i)
{
queue<int> q;
int temp;
bool visited[MaxVertexNum];
AdjList p;
printf("%d",i);
q.push(i);
while(!q.empty())
{
temp=q.front();
q.pop();
for(p=Graph[temp];p!=NULL;p=p->next)
{
if(!visited[p->adjv])
{
visited[p->adjv]=true;
printf("%d ",p->adjv);
q.push(p->adjv);
}
}
}
}