实验九 图的创建与遍历(第12周)

这篇博客介绍了如何使用邻接表数据结构来实现无向图的创建、顶点和边的插入与删除,以及深度优先遍历和广度优先遍历。通过一个C++类`Graphic`,实现了图的各种基本操作,包括判断顶点是否存在、边的连接情况等。
摘要由CSDN通过智能技术生成

实验目的:

  通过上机实验进一步掌握图的存储结构及基本操作的实现。

实验内容与要求:

  分别基于邻接矩阵(不用做)和邻接表存储结构实现图的基本运算,要求:

  ⑴能根据输入的顶点、边/弧的信息建立图;

  ⑵实现图中顶点、边/弧的插入、删除;

  ⑶实现对该图的深度优先遍历;

⑷实现对该图的广度优先遍历。

#include<iostream>
#include<vector>
using namespace std;

class Graphic {
private:
	struct ANode {
		int location;	//位置信息
		int weight;		//权重
		ANode* next;
	};
	struct VNode {
		char name;			//顶点信息;
		ANode* first;		//头结点
		ANode* temp;		//利用临时节点实现尾部插入
		VNode() {
			name = '0';
			first = new ANode;
			first->location = -1;
			first->weight = -1;
			first->next = NULL;
			temp = first;
		}
	};
	vector<VNode>ALGraphic;
	int vexnum = 0;		//顶点数
	int arcnum = 0;		//边数

public:
	void create_Graphic();			//创建图
	void insert_VNode();			//插入顶点
	void delete_VNode();			//删除顶点及其所属边
	void insert_Arc();				//插入边
	void delete_Arc();				//删除边
	void delete_Arc(int i,int j);
	void DFSTraverse();				//深度优先遍历
	void BFSTraverse();				//广度优先遍历
	void print();					//遍历邻接表

	bool exist(char a) {		//判断该点是否在图中,若在则为真
		int z = 0;
		for (unsigned int i = 0; i < ALGraphic.size(); i++) {
			if (ALGraphic[i].name == a)z = 1;
		}
		if (z == 0)return false;
		else {
			return true;
		}
	}
	bool connect(char a, char b,int &x,int &y) {	//判断两个顶点间是否有连接关系,若有则为真
		for (unsigned int i = 0; i < ALGraphic.size(); i++) {
			if (ALGraphic[i].name == a)x = i;
			if (ALGraphic[i].name == b)y = i;
		}
		ANode* p = ALGraphic[x].first->next;
		while (p != NULL) {
			if (p->location == y)return true;
			p = p->next;
		}
		return false;
	}
};

void Graphic::create_Graphic()
{
	cout << "输入顶点数:";
	cin >> this->vexnum;
	for (int i = 0; i < vexnum; i++) {
		cout << "输入第" << i+1 << "个顶点的名称(例:a):";
		VNode node;
		cin >> node.name;
		ALGraphic.push_back(node);
	}
	cout << endl;
	cout << "输入边数:";
	cin >> this->arcnum;
	for (int i = 0; i < arcnum; i++) {
		char a, b;
		int x = 0, y = 0;
		int w;
		cout << "输入第" << i+1 << "条边的信息(顶点1 顶点2 权重)(例:a b 3):";
		cin >> a >> b >> w;
		if (!exist(a)) {
			cout << "顶点" << a << "不存在"<<endl;
			i--;
		}
		else if (!exist(b)) {
			cout << "顶点" << b << "不存在"<<endl;
			i--;
		}
		else {
			if (!connect(a, b, x, y)) {
				ANode* q1 = new ANode;
				q1->next = NULL;
				q1->location = y;
				q1->weight = w;
				ALGraphic[x].temp->next = q1;
				ALGraphic[x].temp = q1;

				ANode* q2 = new ANode;
				q2->next = NULL;
				q2->location = x;
				q2->weight = w;
				ALGraphic[y].temp->next = q2;
				ALGraphic[y].temp = q2;
			}
			else {
				cout << "该边已存在" << endl;
				i--;
			}
		}
	}
	cout << "创建成功!"<<endl;
}

void Graphic::insert_VNode()
{
	vexnum++;
	cout<<endl<< "输入第" << vexnum << "个顶点的名称(例:a):";
	VNode node;
	cin >> node.name;
	ALGraphic.push_back(node);
	cout << "插入成功!" << endl;
}

void Graphic::delete_VNode()
{
	char a;
	cout  << "输入要删除的顶点名称:";
	cin >> a;
	if (!exist(a)) {
		cout << "顶点" << a << "不存在" << endl;
	}
	else {
		int x = 0;
		for (unsigned int i = 0; i < ALGraphic.size(); i++) {
			if (ALGraphic[i].name == a)x = i;
		}

		for (int i = 0; i < vexnum; i++) {
			if (i != x) {
				delete_Arc(x, i);
			}
		}
		ALGraphic.erase(ALGraphic.begin() + x);
		//更新剩余顶点位置
		for (unsigned int i = 0; i < ALGraphic.size(); i++) {
			ANode* p = ALGraphic[i].first->next;
			while (p != NULL) {
				if (p->location >= x)
					p->location = p->location - 1;
				p = p->next;
			}
		}
		vexnum--;
		cout << "顶点" << a << "及其附属边删除成功!" << endl;
	}
}

void Graphic::insert_Arc()
{
	char a, b; int w;
	cout << "插入第" << arcnum << "条边的信息(顶点1 顶点2 权重)(例:a b 3):";
	cin >> a >> b >> w;
	if (!exist(a)) {
		cout << "顶点" << a << "不存在" << endl;
	}
	else if (!exist(b)) {
		cout << "顶点" << b << "不存在" << endl;
	}
	else {
		int x = 0, y = 0;
		if (!connect(a, b, x, y)) {
			ANode* q1 = new ANode;
			q1->next = NULL;
			q1->location = y;
			q1->weight = w;
			ALGraphic[x].temp->next = q1;
			ALGraphic[x].temp = q1;

			ANode* q2 = new ANode;
			q2->next = NULL;
			q2->location = x;
			q2->weight = w;
			ALGraphic[y].temp->next = q2;
			ALGraphic[y].temp = q2;
			cout << "插入成功!"<<endl;
			arcnum++;
		}
		else {
			cout << "该边已存在" << endl;
		}

	}
}

void Graphic::delete_Arc()
{
	char a, b;
	cout<< "输入需删除的边(例:a b):";
	cin >> a >> b;
	int i, j;
	if (!exist(a)) {
		cout << "顶点" << a << "不存在" << endl;
	}
	else if (!exist(b)) {
		cout << "顶点" << b << "不存在" << endl;
	}
	else if (!connect(a, b,i,j)) {
		cout << "边" << a << b << "不存在"<<endl;
	}
	else {
		ANode* p1 = ALGraphic[i].first;
		ANode* q1 = p1->next;
		while (q1 != NULL) {
			if (q1->location == j) {
				p1->next = q1->next;
			}
			p1 = p1->next;
			q1 = q1->next;
		}

		ANode* p2 = ALGraphic[j].first;
		ANode* q2 = p2->next;
		while (q2 != NULL) {
			if (q2->location == i) {
				p2->next = q2->next;
			}
			p2 = p2->next;
			q2 = q2->next;
		}
		arcnum--;
		cout<< "边" << a << b << "删除成功!" << endl;
	}
}

void Graphic::delete_Arc(int i, int j) {
	if (connect(ALGraphic[i].name, ALGraphic[j].name, i, j)) {
		ANode* p1 = ALGraphic[i].first;
		ANode* q1 = p1->next;
		while (q1 != NULL) {
			if (q1->location == j) {
				p1->next = q1->next;
			}
			p1 = p1->next;
			q1 = q1->next;
		}

		ANode* p2 = ALGraphic[j].first;
		ANode* q2 = p2->next;
		while (q2 != NULL) {
			if (q2->location == i) {
				p2->next = q2->next;
			}
			p2 = p2->next;
			q2 = q2->next;
		}
		arcnum--;
	}
}

void Graphic::DFSTraverse()
{
	cout<< "无向图的深度优先遍历结果为:";
	int *v = new int[vexnum]();		//记录数组
	int i = 0;
	while (1) {
		if (v[i] != 1) {
			cout << ALGraphic[i].name;
			v[i] = 1;
			ANode *p= ALGraphic[i].first->next;
			while (p!=NULL) {
				if (v[p->location] != 1) {
					i = p->location;
					break;
				}
				p = p->next;
			}

		}
		else {
			if(i<vexnum-1)
			i++;
		}

		//判断是否全部遍历
		int b = 0;
		for (int j = 0; j < vexnum; j++) {
			if (v[j] != 1)b = 1;
		}	
		if (b == 0)break;
	}
	cout << endl;
}

void Graphic::BFSTraverse()
{
	cout << "无向图的广度优先遍历结果为:";
	int* v = new int[vexnum]();		//记录数组
	int i = 0;
	while (1) {
		if (v[i] != 1) {
			cout << ALGraphic[i].name;
			v[i] = 1;
			int j = i;
			ANode* p = ALGraphic[i].first->next;
			while (p != NULL) {
				if (v[p->location] != 1) {
					i = p->location;
					cout << ALGraphic[i].name;
					v[i] = 1;
				}
				p = p->next;
			}
			if (i < vexnum - 1)i = j + 1;
		}
		else {
			if (i < vexnum - 1)
				i++;
		}

		//判断是否全部遍历
		int b = 0;
		for (int j = 0; j < vexnum; j++) {
			if (v[j] != 1)b = 1;
		}
		if (b == 0)break;
	}
	cout << endl;
}

void Graphic::print()
{
	for (unsigned int i = 0; i < ALGraphic.size(); i++) {
		cout << ALGraphic[i].name << "(" << i << "):";
		ANode* p = ALGraphic[i].first->next;
		while (p != NULL) {
			cout << ALGraphic[p->location].name << "(" << p->location << ")";
			p = p->next;
		}
		cout << endl;
	}
}

//菜单
void show() {
	cout << "---邻接表实现无向图的基本运算---" << endl;
	cout << "1.创建图" << endl;
	cout << "2.插入顶点" << endl;
	cout << "3.删除顶点" << endl;
	cout << "4.插入边" << endl;
	cout << "5.删除边" << endl;
	cout << "6.深度优先遍历" << endl;
	cout << "7.广度优先遍历" << endl;
	cout << "8.遍历邻接表" << endl;
	cout << "0.退出" << endl;
}
int main() {
	Graphic T;
	int n;
	show();
	while (1) {
		cout << endl;
		cin >> n;
		if (n == 1)T.create_Graphic();
		else if (n == 2)T.insert_VNode();
		else if (n == 3)T.delete_VNode();
		else if (n == 4)T.insert_Arc();
		else if (n == 5)T.delete_Arc();
		else if (n == 6)T.DFSTraverse();
		else if (n == 7)T.BFSTraverse();
		else if (n == 8)T.print();
		else {
			break;
		}
	}
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值