求建议,数据结构图的最小生成树普里姆算法实现思路
上周周六周日两天用C写Prim没写出来,用AI写看答案也没看懂AI写的啥意思给自己破防了。我觉得一定问题出在我想到啥写啥,所有今天自习一个半小时就死磕这个**算法怎么实现。。。。。。。目前我认为我思路就这样了,不严谨。步骤哪里需要改进什么的求建议我听劝!!!不把思路写完干脆先不敲这个算法了。。。。。。
//第一步:构造无向连通网 // 顶点表如何设计?只有权值? // 边如何存储?邻接矩阵、邻接表、十字链表、邻接多重表 //普里姆算法(调用需要给网指针,起点在顶点表的下标) //MST性质 //点集T到点集T-T0的最小权值边一定在他的最小生成树中 //第二步:构造辅助数组 // 两个辅助数组,一个T0存最小生成树的点集,一个T-T0存还没放入最小生成树的网点 // 点集后续需要频繁的T-T0删除点,T0插入点,所以可以用链表存储 // 两个辅助数组,一个E0存最小生成树的边集,一个E-E0存还没放入过最小生成树的边集 // 为了找回路时深度优先遍历和边的插入方便,所以给T0的结点加一个邻接多重表指针,用邻接多重表存储E0 // E-E0频繁的遍历每个边以及根据找最小权值边时还需要每个不存在的边表示出来,所有用邻接矩阵存储,这样可以遍历所有对应点的边 // 两个辅助数组,一个V存最小权值边的权值和边上在T-T0中的顶点,一个P存最小权值边上两个顶点中在T0中的那个顶点下标 // 因为后续固定使用,所以用数组存储 // 选择起点进入普里姆算法,把起点放入T0 //第三步:找最小权值边,E-E0移出放入E0 // 1.如何找T0和T-T0间点的最小权值边? // 假设有无向网有n个顶点则一个顶点最多存在n-1条边,对每个顶点都成立 // 所以,辅助边数组需要创建长度为n的边集合V,初始化每个值为无穷大 // 遍历T0的每个点i对所有点j的边权值temp,若存在边(i,j)权值为temp<V[i],则V[i]存temp表示在T0的所有点中到i的边最小权值为temp // 也就是把T0到T-T0的最小权值边转换成T0的指向固定点的最小权值边中找最小权值边 // 这样不知道该边的左顶点是谁,所有需要另外开辟一个长度为n的辅助数组P来存放左顶点在顶点表中的下标 // 即,P[i]=j表示边(i,j)且边的权值存在V[i]中,这个V[i]存的是T0中所有点到点i的权值最小的那条边权值 // 2.如何快速便捷的遍历找到对于点n0到整个网所有点的边的权值? // 需要讨论无向网的边的存储结构 // 邻接表和邻接多重表或者十字链表的话: // 会存在找不到边的情况、需要把找不到边的所有权值默认为无穷大 // 邻接矩阵:不存在找不到对应边但是更加占用内存空间 // 选择邻接矩阵存储E-E0,这样查找到点对其他点成的边效率为O(1)不会遍历到其他多余的边 // 假设使用邻接多重表来存储E-E0那么可以设计顶点表中结点新增一个int m,m为1则在表中,0在最小生成树中 // 找最小权值边时m=0时和遍历他的边找不到对应边时设边权值为无穷大 // 相较使用邻接矩阵效率节省了空间牺牲了时间(当前的我认为操作大量数据时用这个比用邻接矩阵好,只是实现一次练习时邻接矩阵更容易实现) // 假设使用十字链表节省了空间左边的顶点表设计与邻接多重表时设计相同 // 找对应边时不能直接找到,但是可以利用找到的边,假设找边(i,j)在十字链表找到第i行然后遍历边找j // 若找到边(i,m),m>j则不存在边(i,j)此时比邻接多重表更快、若m<j则接着遍历直到找到或者m>j或者下一级指针为空遍历完毕 // 相较使用邻接多重表存储找不存在的边时好一些 // 个人认为十字链表相较邻接多重表存储更好,但是邻接矩阵最快(不考虑构造 // 假设有许多个顶点复杂的网,网占内存大小20G // 用十字链表来做会出现20G大小的临时辅助结构 // 用邻接矩阵存储的话辅助结构会远超20G内存大小 // 3.如何缩减辅助结构大小? // 直接用网E-E0就可以省去这个辅助结构 // 那么如何将网还原?可以把E0遍历给网加边 // 所以!!!!!!!!!!!! // 我需要的辅助数组有T-T0来存放还剩哪些点、一个新网 //第四步:检查是否存在回路,若存在则重新找一条最小权值边,将导致存在回路的边从E0移除 // 1.如何检查加入该边是否存在回路? // 在辅助数组V中找到本次的最短边V[i],若有回路则V[i]需要重新找最短边,别的不需要 // 解决想法是: // 初始、创建一个串,从加入的新边的左顶点作为起点出发,把顶点加入串中 // 更新、接着图的深度优先遍历每经过一个顶点就加入串中,然后检查新加顶点在串中是否已经存在,若存在则出现回路 // 深度遍历完整的完成则没有回路 // 因为图的总点数固定所有串用数组存储存点在顶点表中的下标 //循环以上步骤直至T-T0集合为空集