1. 程式人生 > >鄰接表的c++實現 及 Dijkstra演算法

鄰接表的c++實現 及 Dijkstra演算法

鄰接表的c++

#define maxSize 5
#define INFINITY 10000 //代表無窮

typedef char Vertex;//節點型別
typedef int edge;//邊上權值型別
				 
//邊節點
class edgeNode
{
public:
	edgeNode();
	~edgeNode();

	int adjvex;
	edge weight;
	edgeNode *next;
private:
};
edgeNode::edgeNode()
{
	adjvex = -1;
	weight = -1;
	next = NULL;
}
edgeNode::~edgeNode()
{
}

//頂點節點
class vertexNode
{
public:
	vertexNode();
	~vertexNode();

	int subscript;//下標    
	Vertex data;
	edgeNode *firstEdge;
private:
};
vertexNode::vertexNode()
{
	data = '0';
	firstEdge = NULL;
}
vertexNode::~vertexNode()
{
}

class graphList
{
public:
	graphList(int numVertxnode, int numEdgenode);
	~graphList();
	void addEdge(int v1, int v2, int weight);//新增節點
	void display();
	void Dijkstra(int choose);
	void Dijkstra_2();
	vertexNode vertxnode[maxSize];//頭節點順序表
	int numVertxnode, numEdgenode;//節點數目、邊數
private:
};
graphList::graphList(int numVertxnode, int numEdgenode)
{
	this->numEdgenode = numEdgenode;
	this->numVertxnode = numVertxnode;
}
graphList::~graphList()
{
}
void graphList::addEdge(int v1, int v2, int weight)
{
	edgeNode *temp;
	temp = new edgeNode();
	temp->weight = weight;
	temp->adjvex = v2;
	temp->next = vertxnode[v1].firstEdge;
	vertxnode[v1].firstEdge = temp;

	temp = new edgeNode();//無向圖的反向新增
	temp->weight = weight;
	temp->adjvex = v1;
	temp->next = vertxnode[v2].firstEdge;
	vertxnode[v2].firstEdge = temp;
}
void graphList::display()
{
	edgeNode *p;
	p = new edgeNode();
	for (int i = 0; i < numVertxnode; i++)
	{
		p = vertxnode[i].firstEdge;
		cout << vertxnode[i].data << ":  ";
		while (p)
		{
			cout << p->adjvex << " " << p->weight << " -> ";
			p = p->next;
		}
		cout << endl;
	}
}
Dijkstra演算法
void graphList::Dijkstra(int choose)
{
	vertexNode v, v2;
	edgeNode *temp;
	char p, q = 0;
	switch (choose)//1為單源到所有節點,2為兩個節點之間的最短距離
	{
	case 0:exit(1);
	case 1:cout << "請輸入查詢節點名稱: " << endl;
		cin >> p; break;
	case 2:cout << "請輸入查詢起點名稱: " << endl;
		cin >> p;
		cout << "請輸入查詢終點名稱: " << endl;
		cin >> q;
	}

	int min, Final[maxSize], k, *a;//final用來儲存到各節點的最短距離;*a作為返回值
	int  kn[maxSize];//kn是否找到最短路徑
	for (int i = 0; i < numVertxnode; i++)//
	{
		if (vertxnode[i].data == q)
		{
			v2 = vertxnode[i];
		}
		if (vertxnode[i].data == p)
		{
			v = vertxnode[i];
			temp = v.firstEdge;
			Final[i] = 0;
			kn[i] = 1;
		}
		else {
			Final[i] = INFINITY;
			kn[i] = 0;
		}
	}
	if (v.data == '0' || (v2.data == '0'&&choose == 2))
	{
		cout << "輸入點有誤!" << endl;
		return;
	}
	else
	{
		while (temp)
		{
			Final[temp->adjvex] = temp->weight;
			temp = temp->next;
		}
	}

	min = INFINITY;
	for (int i = 0; i < numVertxnode; i++)//主迴圈
	{
		while (temp)
		{
			if (kn[temp->adjvex] == 0 && temp->weight + min < Final[temp->adjvex])
			{
				Final[temp->adjvex] = temp->weight + min;
			}
			temp = temp->next;
		}
		min = INFINITY;
		for (int j = 0; j < numVertxnode; j++)//查詢到v最近的點
		{
			if (min > Final[j] && Final[j] != 0 && kn[j] == 0)
			{
				min = Final[j];
				k = j;//記錄min對於節點序號
			}
		}
		kn[k] = 1;//找到最近節點 
		temp = vertxnode[k].firstEdge;
	} 
 switch (choose)
 {
 case 1:for (int i = 0; i < 5; i++)
 {
  if (vertxnode[i].data != v.data)
  {
   cout << v.data << "到" << vertxnode[i].data << "的最短距離為 " << Final[i] << endl;
  }
 }
     cout << endl; break;
 case 2:cout << p << "到" << q << "的最短距離為 " << Final[v2.subscript] << endl;
  cout << endl;
 }