1. 程式人生 > 其它 >資料結構 圖 鄰接表表示法

資料結構 圖 鄰接表表示法

技術標籤:資料結構資料結構有向圖c++指標連結串列

圖 鄰接表表示法

圖的鄰接矩陣表示法看這裡

基本結構

template<typename InfoType>
struct ArcNode
{
	int adjvex;
	ArcNode* nextarc;
	InfoType* info;
};

template<typename VertexType, typename InfoType>
struct VNode
{
	VertexType data;
	ArcNode<InfoType>* firstarc;
};

template<
typename VertexType, typename InfoType> using AdjList = VNode<VertexType, InfoType>[MAX_VERTEX_NUM]; template<typename VertexType, typename InfoType> struct ALGraph { AdjList<VertexType, InfoType> vertices; int vexnum, arcnum; GraphKind kind; };

基本操作

初始化
初始化圖的基本資料,每個頂點的指標域置空

template<typename VertexType, typename InfoType>
Status initALGraph(ALGraph<VertexType, InfoType>& ALG, GraphKind kind)//初始化
{
	for (int i = 0; i < MAX_VERTEX_NUM; i++)
		ALG.vertices[i].firstarc = NULL;
	ALG.kind = kind;
	ALG.arcnum = 0;
	ALG.vexnum = 0;
	return OK;
}

查詢頂點在陣列中的位置
遍歷所有頂點,若找到返回下標,未找到返回-1

template<typename VertexType, typename InfoType>
int indexOf(ALGraph<VertexType, InfoType>ALG, VertexType vex)//尋找vex在陣列中的下標,未找到返回-1
{
	for (int i = 0; i < MAX_VERTEX_NUM; i++)
	{
		if (vex == ALG.vertices[i].data)
			return i;
	}
	return -1;
}

插入頂點
將新的頂點加入到頂點陣列尾部

template<typename VertexType, typename InfoType>
Status insertVex_ALG(ALGraph<VertexType, InfoType>& ALG, VertexType vex)//插入頂點
{
	ALG.vertices[ALG.vexnum++].data = vex;
	return OK;
}

插入邊
先找到源目頂點在頂點陣列中的位置,然後用頭插法將目的頂點的位置資訊插入到源頂點指標域的第一個位置

template<typename VertexType, typename InfoType>
Status insertArc_ALG(ALGraph<VertexType, InfoType>& ALG, VertexType from, VertexType to, InfoType dist)//插入邊
{
	int index_f = indexOf(ALG, from);
	int index_t = indexOf(ALG, to);
	ArcNode<InfoType>* p = new ArcNode<InfoType>;
	p->adjvex = index_t;
	p->info = new InfoType(dist);
	p->nextarc = ALG.vertices[index_f].firstarc;//頭插法
	ALG.vertices[index_f].firstarc = p;
	ALG.arcnum++;
	return OK;
}

建立圖
從檔案中讀取資料,建立圖,檔案格式與鄰接矩陣表示法相同,需要用到插入頂點和插入邊的相應函式

檔案格式:
vexnum arcnum
vex1 vex2 ……
vexn1 vexm1 distance
vexn2 vexm2 distance
……

template<typename VertexType, typename InfoType>
Status creatALGraph(ALGraph<VertexType, InfoType>& ALG, string fileName)//從檔案建立圖
{
	ifstream ifs;
	ifs.open(fileName);
	int vexnumInFile, arcnumInFile;
	ifs >> vexnumInFile >> arcnumInFile;
	VertexType vex;
	for (int i = 0; i < vexnumInFile; i++)
	{
		ifs >> vex;
		insertVex_ALG(ALG, vex);
	}
	VertexType from, to;
	InfoType dist;
	for (int i = 0; i < arcnumInFile; i++)
	{
		ifs >> from >> to;
		if (ALG.kind == UDG || ALG.kind == DG)//判斷型別,圖的權值均為1
			dist = 1;
		else//網需要賦具體的權值
			ifs >> dist;
		insertArc_ALG(ALG, from, to, dist);
		if (ALG.kind == UDG || ALG.kind == UDN)//無向需要繼續插入to到from的邊
			insertArc_ALG(ALG, to, from, dist);
	}
	return OK;
}

列印圖
以鄰接表的形式打印出圖

template<typename VertexType, typename InfoType>
Status printALGraph(ALGraph<VertexType, InfoType>ALG)//列印圖
{
	ArcNode<InfoType>* p;
	for (int i = 0; i < ALG.vexnum; i++)
	{
		cout << "[" << i << "]" << ALG.vertices[i].data;
		p = ALG.vertices[i].firstarc;
		while (p)
		{
			cout << " --> [" << p->adjvex << "]" << ALG.vertices[p->adjvex].data << "(" << *(p->info) << ")";
			p = p->nextarc;
		}
		cout << endl;
	}
	return OK;
}

使用的圖仍然是這個:
7 10
北京 西安 鄭州 徐州 成都 廣州 上海
北京 西安 2553
北京 鄭州 695
北京 徐州 704
徐州 上海 651
鄭州 徐州 349
西安 鄭州 511
西安 成都 812
成都 廣州 2368
廣州 鄭州 1579
廣州 上海 1385
在這裡插入圖片描述