ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

浙大数据结构 File Transfer 路径压缩、按秩归并

2021-09-04 12:32:50  阅读:161  来源: 互联网

标签:arr num1 int Transfer 浙大 File root1 节点 root2


老规矩,先把何老师的PPT安排一下,后面直接上代码

一、集合的表示及查找

  

  

 二、集合的简化表示

 

 测试:

三、程序框架的搭建

  

 

 四、按秩归并(对Union函数的改进)

 

姥姥推荐使用比规模 !!!

五、路径压缩(对Find()函数的改进)

尾递归在系统中可能会自动转化为优化后的循环代码,所以可以放心使用。

六、疑惑点解答:

1.在Find()函数中的第二步递归操作等价于:arr[Xn]=arr[Xn-1]=...=arr[X0]=X0,相当于是把根节点的编号作为前面递归的所有节点的父节点(通过赋值操作来让自己成为其他节点的父节点)。

2.对于根节点arr[Xi]=-规模,而其他的一般节点arr[Xj]里面保存的是Xj父节点的下标Xi。

3.Q:Union()函数到底是如何把儿子节点挂在父节点上的?

   A:如上所述,首先比较两个父节点谁的规模更大,将较小的规模加到较大规模上,其次将root2的父节点即arr[root2]用root1下标来覆盖,这样身为父亲的root2里面的元素arr[root2]就变成了父节点的位置(是一个正数),他自己自然不能再做父亲了(因为所有父节点的数据域均保存的是-孩子的规模),但是依旧瘦死的骆驼比马大,因为他的儿子节点的数据域依旧记录这他的位置,只不过孩子要想找到真正的祖先还要继续向父节点的再上一层去寻找。

 七、以下是代码详解(保姆级教程):

#include<iostream>
using namespace std;
const int MaxSize = 100;
typedef int ElementType;
void Init(ElementType arr[], int N) {
	for (int i = 0;i < N;i++)
		arr[i] = -1;//规模设置为1,父节点就是自身
}
//查找根节点,返回值是根节点的下标(路径压缩)
int Find(ElementType arr[], int num) {
	if (arr[num] < 0)
		return num;	//根节点存放的数据是:-规模
	else  // 1. 找到根  2. 把根变成 x 的父结点  3.再返回根 
		return arr[num] = Find(arr, arr[num]);//最内层返回的是根节点的下标,然后依次传给其他节点的数据域,作为其他节点的父节点
}

//合并根节点:把编号为num1和num2的计算机合并(num1,num2已经是根节点了)
void Union(ElementType arr[], int root1, int root2) {
	//默认已经是根节点了
	if (arr[root1] < arr[root2]) {
		arr[root1] += arr[root2];
		arr[root2] = root1;	//将root2的父节点即arr[root2]设置为root1,arr[root2]是指root2的根节点
	}
	else {
		arr[root2] = arr[root1];
		arr[root1] = root2;
	}
}
//连接两台计算机
void Input_connection(ElementType arr[]) {
	int num1, num2;//num1,num2为计算机的实际编号
	cout << "请输入需要连接的两台计算机的编号:";
	cin >> num1 >> num2;
	int root1 = Find(arr, num1);
	int root2 = Find(arr, num2);
	if (root1 != root2)
		Union(arr, root1, root2);
}
//检查两台计算机之间是否已经相连
void check_connection(ElementType arr[]) {
	int num1, num2;
	cout << "请输入需要查询是否连接的两台计算机的编号:";
	cin >> num1 >> num2;
	int root1 = Find(arr, num1);
	int root2 = Find(arr, num2);
	if (root1 != root2) cout << "未连接" << endl;
	else cout << "已连接" << endl;
}
//检查整个计算机网络是否相连
void check_internet(ElementType arr[],int N) {
	int cnt = 0;
	for (int i = 0;i < N;i++)
		if (arr[i] < 0)
			cnt++;
	if (cnt == 1) cout << "The network is connected." << endl;
	else cout << "The network is " << cnt << " part connected." << endl;
}
int main() {
	int N;
	char in;
	cout << "请输入机房的计算机总数:";
	cin >> N;
	cout << "输入操作指南(I:将两台计算机联通 C:检查两个网络之间是否连通 S:检查整个网络是否连通)" << endl;
	ElementType arr[MaxSize];
	Init(arr, N);
	do {
		cout << "请输入操作:";
		cin >> in;
		switch (in)
		{
		case'i':Input_connection(arr);break;
		case'c':check_connection(arr);break;
		case's':check_internet(arr, N);break;
		default:
			break;
		}
	} while (in != 's');
	system("pause");
	return 0;
}

标签:arr,num1,int,Transfer,浙大,File,root1,节点,root2
来源: https://blog.csdn.net/Tandy12356_/article/details/120076454

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有