b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

数据结构-图形(相邻链表)

电脑杂谈  发布时间:2020-06-09 00:05:17  来源:网络整理

数组结构与链表结构堆栈队列_链表结构 java代码_链表的结构

邻接矩阵好吗?这是一种图形存储结构,但是我们还发现,对于边和顶点数量相对较少的图形,这种结构会浪费存储空间. 例如,如果我们要处理如下所示的稀疏有向图,则邻接矩阵中除了arc [1] [0]权重值外没有其他弧. 实际上,这些存储空间是浪费的.

在这里插入图片描述

因此,选择一个新的数据结构来存储此稀疏图尤为重要. 这时,链表结构用于存储原始连接信息.

在这里插入图片描述

链表结构 java代码_链表的结构_数组结构与链表结构堆栈队列

//图的邻接链表存储结构
//边表节点结构,一个adjvex用来存储邻接点的位置,一个next指针用来指向下一个节点
typedef struct EdgeNode
{
	int adjvex;  //存储顶点下标信息
	struct EdgeNode *next;
} EdgeNode;
//顶点表节点结构
typedef struct
{
	string Vexs;  //用来存储顶点信息
	EdgeNode *firstedge;  //用来存储当前顶点的下一个顶点
} VexList;
//这里用动态数组存储顶点表,然后numVertex,numEdge是一个图的顶点数和边数
typedef struct
{
	vector<VexList> VexList;
	int Vertexs, Edges;
} GraphList;

此处用于创建边表的方法是尾部插值方法. “词头数据结构”使用词头插值方法. 就个人而言链表的结构,尾部插值方法更容易理解. 其他方面与邻接矩阵创建图时的想法基本相同.

void CreateGraph(GraphList * G)
{
	string v1, v2;
	EdgeNode * e, *p, *q;
	cout << "请输入顶点数和边数:" << endl;
	cin >> G->Vertexs >> G->Edges;
	cout << "请输入顶点的信息:" << endl;
	for (int i = 0; i < G->Vertexs; ++i){
		VexList tmp;
		cin >> tmp.Vexs;
		tmp.firstedge = NULL;
		G->VexList.push_back(tmp);
	}
	for (int k = 0; k < G->Edges; ++k){
		int i, j;//(Vi,Vj)
		cout << "请输入边(Vi,Vj):" << endl;
		cin >> i >> j;
		if (G->VexList[i].firstedge == NULL){//当前顶点i后面没有顶点
			e = new EdgeNode;
			e->adjvex = j;
			e->next = NULL;
			G->VexList[i].firstedge = e;
		}
		else{  //当前i后面有顶点
			EdgeNode *p = G->VexList[i].firstedge;
			while (p->next){
				p = p->next;
			}
			e = new EdgeNode;
			e->adjvex = j;
			e->next = NULL;
			p->next = e;
		}
		//因为是无向图,所以(Vi,Vj)与(Vj,Vi)都要连接起来
		if (G->VexList[j].firstedge == NULL){ //当前顶点j后面没有顶点
			e = new EdgeNode;
			e->adjvex = i;
			e->next = NULL;
			G->VexList[j].firstedge = e;
		}
		else{  //当前j后面有顶点
			EdgeNode *p = G->VexList[j].firstedge;
			while (p->next){
				p = p->next;
			}
			e = new EdgeNode;
			e->adjvex = i;
			e->next = NULL;
			p->next = e;
		}
	}
}

我还写了一个打印图片的功能.

链表结构 java代码_数组结构与链表结构堆栈队列_链表的结构

//打印连接链表
void PrintGraph(GraphList *G)
{
	cout << "所建立的邻接表如以下所示:" << endl;
	for (int i = 0; i<G->Vertexs; i++){
		cout << G->VexList[i].Vexs;             //先输出顶点信息
		EdgeNode * e = G->VexList[i].firstedge;
		while (e){                           //然后就开始遍历输出每个边表所存储的邻接点的下标
			cout << "-->" << e->adjvex;
			e = e->next;
		}
		cout << endl;
	}
}

此时还需要一个全局访问数组

bool Visited_List[100];

它与基于邻接矩阵的DFS基本相同. 并不是所有的废话,只需直接输入代码即可.

数组结构与链表结构堆栈队列_链表的结构_链表结构 java代码

//DFS
void DFS(GraphList *G, int i)
{
	EdgeNode * p;
	Visited_List[i] = true;
	cout << G->VexList[i].Vexs << "  ";
	p = G->VexList[i].firstedge;
	while (p){
		if (!Visited_List[p->adjvex])
			DFS(G, p->adjvex);
		p = p->next;
	}	
}
void DFSTraver(GraphList *G)
{
	cout << "深度优先遍历顺序:" << endl;
	for (int i = 0; i<G->Vertexs; ++i)
		Visited_List[i] = false;
	for (int i = 0; i<G->Vertexs; ++i){
		if (!Visited_List[i])
			DFS(G, i);
	}
	cout << endl;
}

这里的想法基本上与邻接矩阵相同,也就是说,现在在一个链表中遍历了边表.

//BFS  特点要使用队列,很像树的层序遍历
void BFSTraver(GraphList *G)
{
	cout << "广度优先遍历顺序:" << endl;
	EdgeNode * p;
	queue<int> Q;
	for (int i = 0; i<G->Vertexs; ++i)
		Visited_List[i] = false;
	for (int i = 0; i<G->Vertexs; ++i){
		if (!Visited_List[i]){
			Visited_List[i] = true;
			cout << G->VexList[i].Vexs << "  ";
			Q.push(i);
			while (!Q.empty()){
				i = Q.front();
				Q.pop();
				p = G->VexList[i].firstedge;
				while (p){//把当前顶点下相连接的点找完
					if (!Visited_List[p->adjvex]){
						Visited_List[p->adjvex] = true;
						cout << G->VexList[p->adjvex].Vexs << "  ";
						Q.push(p->adjvex);
					}
					p = p->next;
				}
			}
		}
	}
}

emmmm链表的结构,是时候再次进行测试了. . . 取相同的测试数据,然后输入如下所示的数据.

数组结构与链表结构堆栈队列_链表结构 java代码_链表的结构

在这里插入图片描述

结果:

在这里插入图片描述

结束!

参考以前的人们的工作


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-238794-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...