圖的創建
圖的鄰接矩陣存儲
#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);
}
}
}
}