数据结构(C++)——图(邻接表)

一、改进原因:

以邻接矩阵的形式存储图结构,当e远远小于n^2时,大量的元素都是0。显然,这么多的0元素肯定会造成存储空间的巨大浪费。所以我们将邻接矩阵改进为邻接表。

为此,需要把邻接矩阵的各行分别组织为一个单链表。

如图:


代码:

#include"AllHead.h"
#define MAXSIZE 10
class EdgeNode;

template<class T>
class GrapHL;

template<class T>
class VertexList
{
	friend class GrapHL<T>;
private:
	T data;
	EdgeNode *link;
public:
	VertexList():link(NULL)
	{}
	~VertexList(){}
};
class EdgeNode
{
public:
	int dest;
	EdgeNode *next;
public:
	EdgeNode()
	{
		next = NULL;
	}
	~EdgeNode(){}
};
template<class T>
class GrapHL
{
private:
	VertexList<T> *myv;
	int maxSize;//最大
	int numVertexs;
	int numEdges;
public:
	GrapHL(int sz=MAXSIZE)
	{
		maxSize = sz<=MAXSIZE?MAXSIZE:sz;
		myv = new VertexList<T>[maxSize];
		numVertexs = 0;
		numEdges = 0;
	}
	~GrapHL(){}
public:
	int RemoveVertex(T x)
	{
		int countEdge = 0;
		int v = GetVerticespos(x);
		EdgeNode *fp1 = myv[v].link;
		int temppos;
		while(fp1 != NULL)
		{
			++countEdge;
			temppos = (*fp1).dest;
			EdgeNode *fp2 = myv[temppos].link;
			EdgeNode *fp3 = NULL;
			if((*fp2).dest == v)
			{
				myv[temppos].link = (*fp2).next;
			}
			else
			{
				while(fp2!=NULL && (*fp2).dest!=v)
				{
					fp3 = fp2;
					fp2 = (*fp2).next;
				}
				(*fp3).next = (*fp2).next;
				free(fp2);
			}
			myv[v].link = (*fp1).next;
			free(fp1);
			fp1 = myv[v].link;	
		}
		myv[v].data = myv[numVertexs-1].data;
		myv[v].link = myv[numVertexs-1].link;
		fp1 = myv[v].link;
		EdgeNode *fpm = NULL;
		while(fp1 != NULL)
		{
			temppos = (*fp1).dest;
			fpm = myv[temppos].link;
			while(fpm!=NULL && (*fpm).dest!=numVertexs-1)
				fpm = (*fpm).next;
			(*fpm).dest = v;
			fp1 = (*fp1).next;
		}
		--numVertexs;
		numEdges-=countEdge;
		return OK;
	}
	int RemoveEdge(T x1, T x2)
	{
		int v1 = GetVerticespos(x1);//A
		int v2 = GetVerticespos(x2);//B
		if(v1 == -1||v2 == -1)
		{
			cout<<"有一个节点不存在"<<endl;
			return ERROR;
		}
		EdgeNode *fp1 = myv[v1].link;
		EdgeNode *fp2 = NULL;
		if((*fp1).dest == v2)
		{
			myv[v1].link = (*fp1).next;
		}
		else
		{
			while(fp1!=NULL && (*fp1).dest!=v2)
			{
				fp2 = fp1;
				fp1 = (*fp1).next;
			}
			if(fp1 == NULL)
			{
				cout<<"不存在"<<x1<<"--"<<x2<<"这条边...."<<endl;
				return FALSE;
			}
			(*fp2).next = (*fp1).next;
		}
		free(fp1);
		--numEdges;
		return OK;

	}
	int GetNextNeighbor(T x1,T x2)
	{
		if(numVertexs == 0)
		{
			cout<<"空(GetFirstNeighbor)...";
			return ERROR;
		}
		int v1 = GetVerticespos(x1);
		int v2 = GetVerticespos(x2);
		EdgeNode *fp = myv[v1].link;
		while(fp!=NULL && (*fp).dest != v2)
			fp = (*fp).next;
		if(fp == NULL)
		{
			cout<<"不存在有过链接.....";
			return ERROR;
		}
		fp = (*fp).next;
		if(fp != NULL)
			return (*fp).dest;
		else
		{
			cout<<"没有下一个结点....";
			return ERROR;
		}
	}
	int GetFirstNeighbor(T x)
	{
		if(numVertexs == 0)
		{
			cout<<"空(GetFirstNeighbor)...";
			return ERROR;
		}
		int v = GetVerticespos(x);
		EdgeNode *fp = myv[v].link;
		if(fp != NULL)
			return (*fp).dest;
		else
		{
			cout<<x<<" :没有链接的结点....";
			return ERROR;
		}
	}
	int GetVerticespos(T x)
	{
		if(numVertexs == 0)
		{
			cout<<"空(Getpos)....";
			return FALSE;
		}
		int i;
		for(i=0;i<numVertexs;i++)
		{
			if(myv[i].data == x)
				return i;
		}
		return -1;
		
	}
public:
	int NumOfVertices(){return numVertexs;}
	int NumOfEdge(){return numEdges;}
	int InsertVertex(T x)
	{
		if(numVertexs >= maxSize)
		{
			cout<<"空间已满不能插入...."<<endl;
			return ERROR;
		}
		myv[numVertexs++].data = x;
		return TRUE;
	}
	int InsertEdge(T x1,T x2)//A,B
	{
		int v1 = GetVerticespos(x1);//A
		int v2 = GetVerticespos(x2);//B
		if(v1 == -1||v2 == -1)
		{
			cout<<"有一个节点不存在"<<endl;
			return ERROR;
		}
		EdgeNode *p1 = new EdgeNode;
		(*p1).dest = v2;
		(*p1).next = myv[v1].link;
		myv[v1].link = p1;

		EdgeNode *p2 = new EdgeNode;
		(*p2).dest = v1;
		(*p2).next = myv[v2].link;
		myv[v2].link = p2;
		++numEdges;
	}
	void showGrap()
	{
		for(int i=0; i<numVertexs; ++i)
		{
			cout<<myv[i].data<<"-->";
			EdgeNode *e = myv[i].link;
			while(e != NULL)
			{
				cout<<e->dest<<"-->";
				e = e->next;
			}
			cout<<"Nul."<<endl;
		}
	}

};

测试代码:

#if 0
#include"graphl.h"
int main()
{
	GrapHL<char> gl;
	gl.InsertVertex('A');
	gl.InsertVertex('B');
	gl.InsertVertex('C');
	gl.InsertVertex('D');
	gl.InsertVertex('E');
	gl.InsertVertex('F');
	gl.InsertVertex('G');
	gl.InsertVertex('H');
	gl.InsertVertex('I');
	gl.InsertEdge('A','D');
	gl.InsertEdge('A','B');
	gl.InsertEdge('A','C');
	gl.InsertEdge('B','E');//
	gl.InsertEdge('B','C');
	gl.InsertEdge('F','C');
	gl.InsertEdge('F','D');
	gl.InsertEdge('F','H');
	gl.InsertEdge('E','G');
	gl.InsertEdge('H','I');
//	gl.RemoveEdge('A','B');
//	gl.RemoveEdge('A','C');
//	gl.RemoveEdge('G','C');
	gl.showGrap();
	cout<<gl.NumOfVertices()<<endl;
	cout<<gl.NumOfEdge()<<endl;
	cout<<gl.GetFirstNeighbor('I')<<endl;
	cout<<gl.GetNextNeighbor('A','D')<<endl;
	cout<<gl.GetNextNeighbor('C','G')<<endl;
	cout<<"--------------------------"<<endl;
	gl.RemoveVertex('C');
	gl.showGrap();
	cout<<gl.NumOfVertices()<<endl;
	cout<<gl.NumOfEdge()<<endl;

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值