数据结构实验3 :图的遍历生成树
实验内容及原理
- 键盘输入n个顶点和m条边(6<=n<=16,n-1<=m<=20)及相应权重,建立图的邻居矩阵和邻接表的存储形式,并输出该邻接矩阵和邻接表。
- 用Prim算法求其最小生成树。函数 void Prim(AMGraph G, VerTexType u) 以及输出边集数组的函数 void PrintEdge(Edgeset Sedge, int n)。
- 编写测试程序(即主函数),通过调用上述函数首先建立并输出无向带权图,然后生成最小生成树并输出(即输出边集)。
分析
实验内容比较简单,涉及到的知识主要有:图的存储,遍历,生成最小树算法,并且图的存储要用两种方法实现方式:邻接矩阵和邻接表。
prim 算法主要思路:维护两个集合:当前已经收录的结点集V{} , 和当前v中的结点直接相连的边的集合E{}。 每次从E{}中取出终点不在V{},并且长度最短的一条边,并更新V{},E{},直至全部结点都收录到E{}。从E{}中取出最短的一条边,简单实现可以用数组加遍历的方式,进阶方式是使用优先队列,可以减少时间复杂度和代码长度。
结构表示
//边结构
struct edge{
int from;
int to;
int len;
edge(int f, int t, int l){
from = f; to = t; len = l;
}
};
//用于定义优先队列对节点的排序方式
struct cmp{
bool operator()(edge &a, edge &b){
return a.len > b.len;
}
};
//结点结构
struct grap_node{
int val;
vector<edge>next;
};
邻接表实现
//无向图1,以邻接表为存储形式
class GRAP_one{
vector<grap_node> data;
public:
//展示邻接表
void display(){
cout << "================= display ===============\n";
for (int i = 0; i < data.size(); i++){
cout << i+1; //还原为输入时的数值
for (int y = 0; y < data[i].next.size(); y++){
printf(" -> %d", data[i].next[y].to+1);
}
cout << endl;
}
cout << "==========================================\n";
}
//初始化邻接表
void init(){
cout << "Please input the node number and edge number : >";