数据结构:图(建立及遍历)

图的创建

图的邻接矩阵存储

#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);
			}
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章