圖的表示方法 c++ 實現

圖的表示最長用的兩種方法是:

1)、鄰接矩陣表示法

2)、鄰接表表示


下面是兩種構造圖的方法

1)鄰接矩陣:

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

//枚舉類型,圖的種類 DG:有向圖;WDG:帶權值的有向圖;
//UDG: 無向圖;WUDG: 帶權值的無向圖
enum GraphKind {DG, WDG, UDG, WUDG};

//vertexType頂點類型,VRType:頂點之間的關係類型,InfoType:弧的信息類型
template <typename VertexType, typename VRType, typename InfoType>
class MGraph
{
public:
	MGraph(int vexNum, GraphKind __kind) : vexnum(vexNum), arcnum(0), kind(__kind)
	{
		//分配頂點向量數組
        vvec = new VertexType[vexnum];
		//動態分配二維數組, 注意二維數組的動態分配
        arcs = new ArcCell *[vexnum];
		for (int i = 0; i < vexnum; i++)
		{
			//爲每一行動態分配空間
			arcs[i] = new ArcCell[vexnum];
		}
	}

	void Create()
	{
		switch (kind)
		{
		case DG: 
			{
				CreateDG();    //構造一個有向圖
				break;
			}			
		case WDG:
			{
				CreateWDG();    //構造一個帶權有向圖
				break;
			}
		case UDG:
			{
				CreateUDG();    //構造一個無向圖
				break;
			}
		case WUDG:
			{ 
				CreateWUDG();   //構造一個帶權無向圖
				break;
			}
		default:
			return;
		}
	}

	//初始化頂點數組和鄰接矩陣
	void Init()
	{
		cout << "請輸入每個頂點的關鍵字:" << endl;
		VertexType val;
		for (int i = 0; i < vexnum; i++)
		{
			cin >> val;
			vvec[i] = val;
		}
		for (int i = 0; i < vexnum; i++)
		{
			ArcCell ac;
			ac.adj = 0;
			ac.info = NULL;
			for (int j = 0; j < vexnum; j++)
			{			
                arcs[i][j] = ac;
			}
		}
	}

	//構造一個有向圖
	void CreateDG()
	{
		Init();
		int vhead, vtail;
		cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
		while (cin >> vhead >> vtail)
		{
			arcnum++;
			arcs[vhead][vtail].adj = 1;
		}
	}

	//構造一個帶權有向圖
	void CreateWDG()
	{
		Init();
		int vhead, vtail;
		InfoType w;
		cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
		while (cin >> vhead >> vtail >> w)
		{
			arcnum++;
			arcs[vhead][vtail].adj = w;
		}
	}

	//構造一個無向圖
	void CreateUDG()
	{
		Init();
		int vhead, vtail;
		cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
		while (cin >> vhead >> vtail)
		{
			arcnum += 2;
			arcs[vhead][vtail].adj  = 1;
			arcs[vtail][vhead].adj  = 1;
		}
	}

	//構造一個帶權無向圖
	void CreateWUDG()
	{
		Init();
		int vhead, vtail;
		InfoType w;
		cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
		while (cin >> vhead >> vtail >> w)
		{
			arcnum += 2;
			arcs[vhead][vtail].adj = w;
			arcs[vtail][vhead].adj = w;
		}
	}

	void displayGraph()
	{
		cout << "總共有" << vexnum << "個頂點," 
			 << arcnum << "條邊" << endl;
		for (int i = 0; i < vexnum; i++)
		{
			cout << "第" << i+1 << "個頂點是:" << vvec[i] 
			     << "相鄰的邊有: ";
		    for (int j = 0; j < vexnum; j++)
		    {
				if (arcs[i][j].adj != 0)
					cout << vvec[j] << "(" << arcs[i][j].adj << ") "; 
		    }
			cout << endl;
		}
	}

private:
    struct ArcCell
	{
		VRType adj;   //頂點關係類型。對於無權圖,用1或0表示
		              //表示相鄰與否;對帶權圖,爲權值類型
		InfoType info;  //該弧相關的信息的指針
	};
	VertexType *vvec;          //頂點向量
	ArcCell **arcs;    //鄰接矩陣
	int vexnum;                       //圖的當前頂點個數
	int arcnum;                       //圖的弧數
    GraphKind kind;                   //圖的種類標誌
};

int main()
{
	cout << "構造無向圖:" << endl;
	MGraph<char, int, int> udgGraph(8, UDG);
	udgGraph.Create();
	udgGraph.displayGraph();

	cout << "構造帶權無向圖:" << endl;
	MGraph<char, int, int> wudgGraph(9, WUDG);
	wudgGraph.Create();
	wudgGraph.displayGraph();

	cout << "構造有向圖:" << endl;
	MGraph<char, int, int> dgGraph(6, DG);
	udgGraph.Create();
	udgGraph.displayGraph();

	cout << "構造帶權有向圖:" << endl;
	MGraph<char, int, int> wdgGraph(6, WDG);
	wdgGraph.Create();
	wdgGraph.displayGraph();

	system("pause");
	return 0;
}
運行了一個帶權有向圖:


2)鄰接鏈表


#include <iostream>
using namespace std;

//枚舉類型,圖的種類 DG:有向圖;WDG:帶權值的有向圖;
//UDG: 無向圖;WUDG: 帶權值的無向圖
enum GraphKind {DG, WDG, UDG, WUDG};

template<typename VertexType, typename InfoType>
class ALGraph
{
public:
	ALGraph(int verNum, GraphKind _kind) 
		: vexnum(verNum), arcnum(0), kind(_kind)  
	{
		for (int i = 0; i < MAX_VERTEX_NUM; i++)
			vertices[i].firstarc = NULL;
	}

	//構造圖,進行選擇
	void Create()
	{
		switch (kind)
		{
		case DG: 
			{
				CreateDG();    //構造一個有向圖
				break;
			}			
		case WDG:
			{
				CreateWDG();    //構造一個帶權有向圖
				break;
			}
		case UDG:
			{
				CreateUDG();    //構造一個無向圖
				break;
			}
		case WUDG:
			{ 
				CreateWUDG();   //構造一個帶權無向圖
				break;
			}
		default:
			return;
		}
	}
	
	//打印鄰接鏈表
	void displayGraph()
	{
		for (int i = 0; i < vexnum; i++)
		{
			cout << "第" << i+1 << "個頂點是:" << vertices[i].data
				<< " 鄰接表爲: ";
			ArcNode *arcNode = vertices[i].firstarc;
			while (arcNode != NULL)
			{
				cout << " -> " << vertices[arcNode->adjvex].data
					<< "(" << arcNode->info << ")";
				arcNode = arcNode->nextarc;
			}
			cout << endl;
		}
	}

private:
	//初始化鄰接鏈表的表頭數組
	void InitVertics()
	{
		cout << "請輸入每個頂點的關鍵字:" << endl;
		VertexType val;
		for (int i = 0; i < vexnum; i++)
		{
			cin >> val;
			vertices[i].data = val;
		}
	}

	//插入一個表結點
	void insertArc(int vHead, int vTail, InfoType w)
	{
		//構造一個表結點
		ArcNode *newArcNode = new ArcNode;
		newArcNode->adjvex = vTail;
		newArcNode->nextarc = NULL;
		newArcNode->info = w;

		//arcNode 是vertics[vHead]的鄰接表
		ArcNode *arcNode = vertices[vHead].firstarc;
		if (arcNode == NULL)
			vertices[vHead].firstarc = newArcNode;
		else
		{
			while (arcNode->nextarc != NULL)
			{
				arcNode = arcNode->nextarc;		
			}
			arcNode->nextarc = newArcNode;
		}
		arcnum++;
	}

	//構造一個有向圖
	void CreateDG()
	{
		InitVertics();
		int vhead, vtail;
		cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
		while (cin >> vhead >> vtail)
		{
			insertArc(vhead, vtail, 0);
		}
	}

	//構造一個帶權有向圖
	void CreateWDG()
	{
		InitVertics();
		int vhead, vtail;
		InfoType w;
		cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
		while (cin >> vhead >> vtail >> w)
		{
			insertArc(vhead, vtail, w);
		}
	}

	//構造一個無向圖
	void CreateUDG()
	{
		InitVertics();
		int vhead, vtail;
		cout << "請依次輸入每條邊的開始頂點和結束頂點:" << endl;
		while (cin >> vhead >> vtail)
		{
			insertArc(vhead, vtail, 0);
			insertArc(vtail, vhead, 0);
		}
	}

	//構造一個帶權無向圖
	void CreateWUDG()
	{
		InitVertics();
		int vhead, vtail;
		InfoType w;
		cout << "請依次輸入每條邊的開始頂點和結束頂點和權值:" << endl;
		while (cin >> vhead >> vtail >> w)
		{
			insertArc(vhead, vtail, w);
			insertArc(vtail, vhead, w);
		}
	}


	//const數據成員必須在構造函數裏初始化
	static const int MAX_VERTEX_NUM = 20;  //最大頂點個數


	struct ArcNode          //表結點
	{
		int adjvex;        //該弧所指向的頂點的位置
		ArcNode *nextarc;  //指向下一條弧的指針
		InfoType info;     //該弧相關信息的指針
	};
	struct VNode           //頭結點
	{
		VertexType data;    //頂點信息
		ArcNode *firstarc;  //指向第一條依附於該頂點的弧的指針
	};

	/*VNode AdjList[MAX_VERTEX_NUM];*/ 
	/* AdjList[MAX_VERTEX_NUM] vertices;*/
	VNode vertices[MAX_VERTEX_NUM];
	int vexnum;             //圖的當前頂點數
	int arcnum;             //圖的弧數
	GraphKind kind;         //圖的種類 
};

int main()
{
	cout << "構造一個8個頂點的無向圖:" << endl;
	ALGraph<char, int> udgGraph(8, UDG);
	udgGraph.Create();
	udgGraph.displayGraph();

	cout << "構造一個9個頂點的帶權無向圖:" << endl;
	ALGraph<char, int> wudgGraph(9, WUDG);
	wudgGraph.Create();
	wudgGraph.displayGraph();

	cout << "構造一個6個頂點的有向圖:" << endl;
	ALGraph<char, int> dgGraph(6, DG);
	dgGraph.Create();
	dgGraph.displayGraph();

	cout << "構造一個9個頂點的帶權有向圖:" << endl;
	ALGraph<char, int> wdgGraph(9, WDG);
	wdgGraph.Create();
	wdgGraph.displayGraph();

	system("pause");
	return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章