数据结构——图的十字链表实现

十字链表定义

之前的邻接表对于有向图来说,可分为邻接表和逆邻接表,对于出入度要求不同时,生成的邻接表也不同
十字链表的出现就是将 邻接表和逆邻接表整合在一起
在同一个代码中,对于一个顶点可以找到其出度也可以找到其入度
在十字链表存储结构中,有向图中的顶点表的结点结构如下所示:
在这里插入图片描述
data存储数据,firstIn指向入边表头指针,firstOut指向出边表头指针。
边表结点结构如下
在这里插入图片描述
其中的tailVex表示该弧的弧尾顶点在顶点数组xList中的位置
headVex表示该弧的弧头顶点在顶点数组中的位置
hLink则表示指向弧头相同的下一条弧
tLink则表示指向弧尾相同的下一条弧。
如下图所示的一个有向图:
在这里插入图片描述
在这里插入图片描述

十字链表结构体定义

里面那个inof不知道啥意思

#include<iostream>
using namespace std;
#define MAX 25

typedef char Vertype;
typedef int infotype;//这是权重吗
typedef int Status;

typedef struct Arc_node//弧结点结构
{
	int tailvex, headvex;
	struct Arc_node *hlink, *tlink;
	infotype *info;//这是权重的意思吗?
	int weight;
}Arc_node;

typedef struct Vex_Node//顶点结构
{
	Vertype data;
	Arc_node *firstIn, *firstOut;
}Vex_Node;

typedef struct Or_list//十字链表
{
	Vex_Node list[MAX];//顶点列表
	int Vexnum, Arcnum;//顶点数目 和 边的数目
}Or_list;
//被调用的函数要声明
Status locateVertex(Or_list &G, Vex_Node node);
Status inserArc(Or_list &G, Vex_Node node1, Vex_Node node2);
Status inserArction(Or_list &G, int index1, int index2);

//生成图
Status CreatOr_list(Or_list &G)
{
	cout <<"输入顶点数目和边的数目: " << endl;
	cin >> G.Vexnum;
	cin >> G.Arcnum;

	//初始化
	cout <<"输入"<<G.Vexnum<<"个顶点内容: " << endl;
	for (int i = 0; i < G.Vexnum; i++)
	{
		cin >> G.list[i].data;
		G.list[i].firstIn = NULL;
		G.list[i].firstOut = NULL;
	}

	//增加弧
	for (int j = 0; j < G.Arcnum; j++)
	{
		//此时,只有初始化的十字链表  弧还没有形成,所以这里将形成弧
		Vex_Node node1, node2;
		cout << "请输入第"<<j+1<<"条弧的两个顶点"<< endl;
		cin >> node1.data >> node2.data;
		inserArc(G,node1,node2);
	}
	return 0;
}

//获取两个顶点下标 并生成弧
Status inserArc(Or_list &G, Vex_Node node1, Vex_Node node2)
{
	int index1 = locateVertex(G,node1);//获取下标
	int index2 = locateVertex(G,node2);

	if (index1 == -1 || index2 == -1)
	{
		cout << "顶点不存在"<< endl;
		return NULL;
	}
	inserArction(G,index1,index2);
	return 0;
}

//寻找某一顶点的下标
Status locateVertex(Or_list &G, Vex_Node node)//获取该顶点下标
{
	int i,index=-1;
	for (i = 0; i < G.Vexnum; i++)
	{
		if (G.list[i].data == node.data)
		{
			index = i;
			break;//如果有重复的呢
		}
	}
	return index;
}

//生成弧
Status inserArction(Or_list &G, int index1, int index2)
{
	Arc_node *pArc = new Arc_node;
	pArc->tailvex = index1;
	pArc->headvex = index2;

	pArc->info = NULL;//这一段是什么, 
	pArc->tlink = G.list[index1].firstOut;
	pArc->hlink = G.list[index2].firstIn;

	G.list[index1].firstOut = pArc;
	G.list[index2].firstIn = pArc;

	cout << "输入权重: "<< endl;
	cin>>pArc->weight;
	return 0;
}

//输出图
Status DispGhaph(Or_list &G)
{
	for (int i = 0; i < G.Vexnum; i++)
	{
		//ptail  和phead  可以指向弧的前后顶点位置
		Arc_node *ptail = G.list[i].firstOut;//以i位置顶点为出指针
		Arc_node *phead = G.list[i].firstIn;//以i位置顶点为入指针

		cout << i << " 位置顶点元素为: " << G.list[i].data << endl;
		cout << "输出以" << G.list[i].data << "弧尾结构: " << endl;
		while (ptail)
		{
			cout << G.list[ptail->tailvex].data <<'\t'<< "->" << '\t' << ptail->weight << '\t' << G.list[ptail->headvex].data << endl;
			ptail = ptail->tlink;
		}
		cout << "输出以" << G.list[i].data << "弧头结构" << endl;
		while (phead)
		{
			cout << G.list[phead->headvex].data << '\t' << phead->weight << '\t' << "<-" << '\t' << G.list[phead->tailvex].data << endl;
			phead = phead->hlink;
		}

	}
	return 0;
}
//增加弧
Status ADDGhaphARC(Or_list &G)
{
	//增加新的弧   如果弧原本存在,提示。如果不存在就生成这条弧
	Vex_Node node1, node2;
	int I1=-1, I2=-1;
	cout << "输入两个顶点以便生成弧"<< endl;
	cin >> node1.data >> node2.data;
	for (int i = 0; i < G.Vexnum; i++)
	{
		if (G.list[i].data == node1.data)
		{
			I1 = i;
			break;
		}
	}

	for (int i = 0; i < G.Vexnum; i++)
	{
		if (G.list[i].data == node2.data)
		{
			I2 = i;
			break;
		}
	}

	if (I1 == -1 || I2 == -1)
	{
		cout << "没有这个值"<< endl;
		return NULL;
	}
	else if (G.list[I1].firstOut ==G.list[I2].firstIn)
	{
		cout << "弧原本存在"<< endl;
		return NULL;
	}
	else
	{
		cout << "顶点合法,将生成弧"<< endl;
		inserArction(G,I1,I2);
	}
	return 0;
}

int main()
{
	Or_list G;
	CreatOr_list(G);
	DispGhaph(G);
	ADDGhaphARC(G);
	DispGhaph(G);
	system("pause");
	return 0;
}

在写这个的时候发现前面的额数据结构 都是在顺利的条件下生成 那么如果遇到输入格式或者范围超过时应该写一个提示输入不合规,重新输入的循环体,,,记得下次循环回头时重新编,我打算先将数据结构基础的都过一遍,用c给它写出来,现在开始入门JAVA的坑了,等学了基本的,在将数据结构用JAVA编写,一来练练JAVA 二来巩固完善数据结构

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值