栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数据结构-图(邻接多重表)(c++实现)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数据结构-图(邻接多重表)(c++实现)

#include
using namespace std;

//图的邻接多重表表示法

//邻接多重表在两个顶点有同一个边的情况下只会存储一个边结点	析构时每个节点只能释放一次



class node					//边结点
{
public:
	node(int _x,int _y);
	
	node();
	
	~node();

	node* one, *two;
	
	int x, y;
};

node::node(int _x,int _y) { one = nullptr; two = nullptr; x = _x; y = _y; }

node::node() { one = nullptr; two = nullptr; x = 0; y = 0; }

node::~node() { one = nullptr; two = nullptr; x = 0; y = 0; }



template	//顶点结点
class table
{
public:
	table();
	table(T _data);
	~table();

	T data;

	node* next;
};

template
table::table() { data = NULL; next = nullptr;}

template
table::table(T _data) { data = _data; next = nullptr; }

template
table::~table() { data = NULL; next = nullptr; }


template
class map
{
public:
	map(T _data[],int _len);
	~map();

	void print();

private:

	void remove(table* M);		//清空边结点

	table* M;					//顶点表

	int len;						//表长

	int side;						//边的数量

};


template						//邻接多重表构建图
map::map(T _data[], int _len)
{
	//开辟空间
	
	len = _len - 1;

	M = new table[len];

	for (int i = 0; i < len; i++) { M[i].data = _data[i]; }

	//添加边
	int num;
	cout << "输入边的数量:";
	cin >> num;

	side = num;

	if (num < 0 || num > len * (len - 1) / 2) { cout << "数量有误!" << endl; return; }

	for (int _i = 0; _i < num; _i++)
	{
		int i, j;
		cout << "输入边在数组中的起始位置:";
		cin >> i;
		cout << "输入边在数组中的结束位置:";
		cin >> j;

		//判断下标是否在数组中存在 -- 此处省略

		node* p = new node(i, j);

		if (M[i].next == nullptr) { M[i].next = p; }
		else
		{
			node* temp = M[i].next;
			bool flag = true;
			while (flag)
			{
				if (temp->x == i)							//边的起始位置为当前结点
				{
					if (temp->one != nullptr) { temp = temp->one; }
					else { flag = false; }
				}
				else										//边的结束位置为当前结点
				{
					if (temp->two != nullptr) { temp = temp->two; }
					else { flag = false; }
				}
			}
			if (temp->x == i) { temp->one = p; }			//建立的边以此结点为起始位置
			else { temp->two = p; }							//建立的边以此结点为结束位置
										
		}

		if (M[j].next == nullptr) { M[j].next = p; }
		else
		{
			node* temp = M[j].next;
			bool flag = true;
			while (flag)
			{
				if (temp->y == j)							//边的起始位置为当前结点
				{
					if (temp->two != nullptr) { temp = temp->two; }
					else { flag = false; }
				}
				else										//边的结束位置为当前结点
				{
					if (temp->one != nullptr) { temp = temp->one; }
					else { flag = false; }
				}
			}
			if (temp->x == i) { temp->one = p; }			//建立的边以此结点为起始位置
			else { temp->two = p; }							//建立的边以此节点为结束位置
		}
	}
}

template
void map::print()
{
	for (int i = 0; i < len; i++)
	{
		cout << M[i].data << "tt";
		
		if (M[i].next != nullptr) 
		{ 
			node* temp = M[i].next; 
			bool flag = true;

			while (flag)
			{
				if (temp->x == i)
				{
					cout << temp->x << " " << temp->y << " - ";
					if (temp->one != nullptr) { temp = temp->one; }
					else { flag = false; }
				}
				else 
				{
					cout << temp->x << " " << temp->y << " - ";
					if (temp->two != nullptr) { temp = temp->two; }
					else { flag = false; }
				}
			}
			cout << endl;
		}
	}
}

template			//析构
map::~map() 
{
	remove(M);
	delete[]M;
	M = nullptr;
	len = 0;
	side = 0;
}

template										//清空边结点
void map::remove(table* M)
{
	node** arr = new node*[side];								//存储边结点指针的数组

	int num = 0;

	for (int i = 0; i < len; i++)		
	{
		if (M[i].next != nullptr)
		{
			node* temp = M[i].next;
			bool flag = true;
			while (flag)
			{
				if (temp->x == i)							//x == i 时 该边结点为访问元素所发出的边
				{											//因为边结点是共用的 只记录结点发出的或者接收的即可 -- 此处记录发出的
															//遍历数组中是否存在该边	--	存在则不置入数组 反之置入
					bool ret = true;
					for (int j = 0; j < num; j++) 
					{ 
						if (arr[j]->x == temp->x && arr[j]->y == temp->y) { ret = false; }//该边在数组中存在标志置为false
					}

					if (ret == true) { arr[num] = temp; num++; }				//边不存在 存入数组中数组元素个数+1

					if (temp->one != nullptr) { temp = temp->one; }				//表结点有后继边 继续深入
					else { flag = false; }										//此边结点无后继边 循环结束
				}
				else 
				{
					if (temp->two != nullptr) { temp = temp->two; }				//不为此结点发出的边 进入下一边结点
					else { flag = false; }										//此边结点无后后继边 循环结束
				}
			}
		}
	}

	//测试代码 查看数组中的结点是否为为需要释放的边结点

	

	delete[]arr;
	arr = nullptr;
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/873088.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号