图的存储--邻接多重表

        邻接多重表存储图的方式可以看作是邻接表和十字链表的结合,都是为各顶点建立一个链表;各顶点建立的链表又组合在一起。

        链表头节点:

 其它节点:

        同十字链表的一样,不过很多地方会多一个mark标志域,用来防止再进行操作时,同一无向弧被多次访问。mark为0时,表示为访问过,mark为1时,表示被访问过。不过,我没理解其中的高深之处,mark标志只有一次性,用过一次后变为1,再次使用便不在生效。此处例子,我便不设置mark标志域。

 邻接多重表存储无向图

/*
	邻接多重表主要存储无向图
*/
#define MAX_VERTEX_NUM 10	// 最大顶点数
typedef char verType;		// 顶点类型
typedef string InfoType;	// 弧上信息类型
// 弧
struct ArcNode {
	int tailIndex, headIndex;	// 弧尾、弧头所在数组下标
	ArcNode *tlink, *hlink;		// 分别指向与弧尾、弧头下一个相关的弧
	InfoType* info;				// 弧上信息
};
// 顶点
struct verNode {
	verType vertex;			// 数据域
	ArcNode* firstArc;		// 第一个与该顶点相关的弧
};
// 邻接多重表
struct AMLGraph {
	verNode Vertex[MAX_VERTEX_NUM];		// 顶点数组
	int ver_num;	// 顶点数
	int arc_num;	// 弧数
};
// 获取顶点在数组位置
int LocateVertex(AMLGraph &graph, verType vex) {
	for (int i = 0; i < graph.ver_num; ++i)
		if (graph.Vertex[i].vertex == vex) return i;
	return -1;
}
// 创建邻接多重表
void CreatAMLGraph(AMLGraph &graph) {
	cout << "输入顶点数、边数>>" << endl;
	cin >> graph.ver_num >> graph.arc_num;
	cout << "输入顶点信息>>" << endl;
	for (int i = 0; i < graph.ver_num; ++i) {
		cin >> graph.Vertex[i].vertex;
		graph.Vertex[i].firstArc = NULL;
	}
	verType v1, v2;
	int index1, index2;
	for (int i = 0; i < graph.arc_num; ++i) {
		cout << "输入邻接的顶点" << endl;
		cin >> v1 >> v2;
		index1 = LocateVertex(graph, v1);
		index2 = LocateVertex(graph, v2);
		if (index1 < 0 || index2 < 0) {
			cout << "邻接顶点错误" << endl;
			--i;
			continue;
		}
		ArcNode* arc = new ArcNode();
		arc->tailIndex = index1;
		arc->headIndex = index2;
		arc->tlink = graph.Vertex[index1].firstArc;
		arc->hlink = graph.Vertex[index2].firstArc;
		graph.Vertex[index1].firstArc = arc;
		graph.Vertex[index2].firstArc = arc;
		cout << "弧上是否存储信息" << endl;
		cout << " 1、是   0、否" << endl;
		int Is_info;
		cin >> Is_info;
		if (Is_info) {
			cout << "输入弧上信息" << endl;
			InfoType INFO;
			cin >> INFO;
			arc->info = new InfoType(INFO);
		}
	}
}

 遍历:

// 遍历
void Traverse(AMLGraph &graph) {
	for (int i = 0; i < graph.ver_num; ++i) {
		ArcNode* T = graph.Vertex[i].firstArc;
		while (T) { 
			int index = i == T->headIndex ? T->tailIndex : T->headIndex;
			cout << "顶点 " << graph.Vertex[i].vertex << "<-- -->" << graph.Vertex[index].vertex;
			if (T->info) {
				cout << " 弧上信息:" << *(T->info);
			}
			cout << endl;
			if (i == T->headIndex) T = T->hlink;
			else T = T->tlink;
		}
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对任意给定的(顶点数不小于20,边数不少于30,的类型可以是有向无向图、有向网、无向网),能够输入的顶点和边(或弧)的信息,并存储到相应存储结构(邻接矩阵、邻接表、十字链表、邻接多重表,任选其中两种类型),对自己所创建的完成以下操作: 对无向图求每个顶点的度,或对有向求每个顶点的入度和出度(5分) 完成插入顶点和边(或弧)的功能(5分) 完成删除顶点和边(或弧)的功能(5分) 两种存储结构的转换(5分),如果其中一种存储结构为十字链表或邻接多重表则增加5分。 输出的深度优先遍历序列或广度优先遍历序列(5分) 求的深度优先或广度优先的生成树(或生成森林)(存储结构为孩子-兄弟链表),并对生成树进行遍历(15分) 判断的连通性,输出连通分量的个数(5分) 判断中是否在环,无向图5分,有向10分 给出顶点u和v,判断u到v是否在路径(5分) 10、求顶点u到v的一条简单路径(10分) 11、求顶点u到v的所有简单路径(15分) 12、求顶点u到v的最短路径(10分) 13、求顶点u到其余各顶点的最短路径(15分) 14、求任两个顶点之间的最短路径(15分) 15、求最小生成树(15分) 16、对于有一个源点和一个汇点的有向网,求关键路径(20分) 编程环境可以是C、VC++、JAVA,每位同学从上述题目中选择100分的题目,注意,必须选择第1-6题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值