邻接表的实现

博主依据《大话数据结构》进行代码实现,运行了一遍代码,但尚未研究明白,打算下次再详细说明,还提及了相关头文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
using namespace std;
 
#define maxvex 10
 
struct EdgeNode {
	int adjvex; //连接的顶点
	EdgeNode *next; //指向下一条出边
};
 
struct VertexNode {
	int data; //点的数据
	EdgeNode *firstedge;//指向第一条出边
}AdjList[maxvex];
 
 
//创建图 
void CreateALGraph() {
	int n, m, i, j; //点数 n ,边数 m
	cin >> n >> m;
 
	for (i = 1; i <= n; i++) {
		cin >> AdjList[i].data;
		AdjList[i].firstedge = NULL;//初始化第一条出边为NULL
	}
 //这里是对边的两个端点进行操作
	for (i = 1; i <= m; i++) {
		int v1, v2;
		cin >> v1 >> v2;
		EdgeNode *e;
 
      		//无向图===============================
//这里采用的是头插法  因为是无向图,所以需要这条的两个顶点设置一下.
		e = new EdgeNode;
		e->adjvex = v2;
		e->next = AdjList[v1].firstedge;
		AdjList[v1].firstedge = e;
 
		e = new EdgeNode;
		e->adjvex = v1;
		e->next = AdjList[v2].firstedge;
		AdjList[v2].firstedge = e;
	}
}
 
int main() {
	CreateALGraph();
	return 0;
}


添加链接描述
这是根据大话数据结构这本书上的代码实现的
这里我怕跑了一遍代码,还没有研究明白 .
下次再说清楚把

#pragma once
#include<iostream>
const int queueSize=100;
template<class T>
class queue
{
public:
	T data[queueSize];
	int front,rear;
};


#pragma once 
#include<iostream>
#include"queue.h"
//定义边结点
struct ArcNode{
int adjvex;//邻接点域,存储该顶点对应的下标
ArcNode *next;//链域,指向下一个邻接点
};
//定义顶点表结点
struct VertexNode{
int vertex;//这里是顶点域,存放顶点信息
ArcNode *firstedge;//边表头指针
};
//基于邻接表存储结构的图的实现
const int  MaxSize=10;
int visited[MaxSize]={0};//如果该点没有被访问,则值是0,如果被访问过了 将这个值设为1
template <class T>
class ALGraph{
public:
ALGraph(T a[],int n,int e);//构造函数建立具有n个定点e条边的图,同时也传入一个数组
~ALGraph(){}  //析构函数
void DFSTraaverse(int v);//深度优先遍历图
void BFSTraverse(int v);//广度优先遍历
private:
	VertexNode adjlist[MaxSize];//存放顶点的数组,将顶点放到这个数组里面去
	int vertexNum,arcNum;//图中顶点数和边数
};
template<class T>
ALGraph<T>::ALGraph(T a[],int n,int e)
{
vertexNum=n;//将顶点数赋值给vertexNum
arcNum=e;//将边数赋值给arcNum
for(int i=0;i<vertexNum;i++){//遍历所有的顶点
adjlist[i].vertex=a[i];//将数组的值赋给顶点域 当作顶点信息
adjlist[i].firstedge=NULL;//将边表设置位空表
}
//建立边表
for(int k=0;k<arcNum;k++)//对所有的边进行设置
{
//这里采用了头查法,将新结点s插到头部位置
int i,j;
std::cin>>i>>j;
ArcNode*s=new ArcNode;//新创建一个顶点
s->adjvex=j;//邻接序号为j,
s->next=adjlist[i].firstedge;//将s指针指向当前顶点指向的结点,当前结点一开始指向的第一个结点变成第二个结点,就是挪位到即将插入结点的next位置
adjlist[i].firstedge=s;//将当前顶点的指针指向s,这一步就是将s结点方法当前结点的第一个位置
//与书中给出的代码相比,这里只是设置一条边的一个端点,这里尝试着将其补上
s=new ArcNode;
s->adjvex=i;
s->next=adjlist[j].firstedge;
adjlist[j].firstedge=s;
}
}
template<class T>
//采用内联函数
inline void ALGraph<T>::DFSTraaverse(int v)//深度优先遍历图
{
//输出这个结点在数组中位置
std::cout<<adjlist[v].vertex;
//输出之后标志一下这个结点已经被访问过了
visited[v]=1;
//顺着这个结点遍历下去,先将p指向firstedge的位置
ArcNode*p=adjlist[v].firstedge;
while(p!=NULL){//前提是p不为空的前提下,也就是存在链接表的情况
int j=p->adjvex;//将当前的结点域所指向的下标赋值给j
if(visited[j]==0)//此时表示没有被访问过,采用递归思想进行访问
DFSTraaverse(j);//采用递归的思想,然后这个结点的邻接表位置进行访问
p=p->next;
}
}
template<class T>
//广度有限遍历  都是先给出结点的下标
inline void ALGraph<T>::BFSTraverse(int v){
int visited[MaxSize]={0};//顶点是否被访问的标记
queue<T>Q;//采用队列
Q.front=Q.rear=-1;
std::cout<<adjlist[v].vertex;
visited[v]=1;//标记这个顶点被访问过了
Q.data[++Q.rear]=v;//被访问的顶点入队  将访问过的结点放到队列中去
while(Q.front!=Q.rear)//如果队列不是空队列
{
v=Q.data[++Q.front];//队头元素出队
ArcNode *p=adjlist[v].firstedge;
while(p!=NULL)
{
int j=p->adjvex;//将链表域指向的结点下标值赋值给j
if(visited[j]==0){//如果这个结点没有被访问过
std::cout<<adjlist[j].vertex;
visited[j]=1;
Q.data[++Q.rear]=j;//然后将访问过的点放到队列数组中去,这里将会调到80行的while循环处,将整个图都遍历了
}
p=p->next;//这里是横向遍历邻接表的位置
}
}
}

以上是相关头文件

#include"graph.h"
using namespace std;
int main(){
int arry[]={1,2,3,4,5};
ALGraph<int>graph(arry,5,7);
graph.BFSTraverse(3);
cout<<endl;
graph.DFSTraaverse(3);
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值