小白专场-FileTransfer-c语言实现
更新、更全的《数据结构与算法》的更新网站,更有python、go、人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11407287.html
一、集合的简化表示
在上一节 集合及运算中,我们对集合使用二叉树表示,如下图所示:
为了使用二叉树,我们在上一节中使用以下代码,构造二叉树:
/* c语言实现 */
typedef struct{
ElementType Data;
int Parent;
} SetType;
int Find(SetType S[], ElementType X)
{
// 在数组S中查找值为X的元素所属的集合
// MaxSize是全局变量,为数组S的最大长度
int i;
for (i = 0; i < MaxSize && S[i].Data != X; i++);
if (i >= MaxSize) return -1; // 未找到X,返回-1
for (; S[i].Parent >= 0; i = S[i].Parent);
return i; // 找到X所属集合,返回树根结点在数组S中的下标
}
使用二叉树构造集合,Find操作在差的情况下时间复杂度可能为\(O(n^2)\)
因此对于任何有限集合的(N个)元素都可以被一一映射为整数 0~N-1。即对于集合 {2, 5, 4, 3} 和 {6, 0, 1} 我们可以使用如下图所示的数组表示:
对于上述的数组,我们可以使用如下代码构造:
/* c语言实现 */
typedef int ElementType; // 默认元素可以用非负整数表示
typedef int SetName; //默认用根结点的下标作为集合名称
typedef ElementType SetType[MaxSize];
SetName Find(SetType S, ElementType X)
{
// 默认集合元素全部初始化为-1
for (; S[X] >= 0; X = S[X]);
return X;
}
void Union(SetType S, SetName Root1, SetName Root2)
{
// 这里默认Root1和Root2是不同集合的根节点
S[Root2] = Root1;
}
二、题意理解
根据输入样例,以此来判断计算机之间有多少个组成,如下图所示
上图动态变化如下图所示:
下图为五台计算机之间形成全连接状态,因此看成一个整体:
三、程序框架搭建
/* c语言实现 */
int main()
{
初始化集合;
do {
读入一条指令;
处理指令;
} while (没结束);
return 0;
}
int main()
{
SetType S;
int n;
char in;
scanf("%d\n", &n);
Initialization(S, n);
do {
scanf("%c", &in);
switch (in) {
case 'I': Input_connection(S); break; // Union(Find)
case 'C': Check_connection(S); break; // Find
case 'S': Check_network(S, n); break; // 数集合的根,判断计算机网络的组成个数
}
} while (in != 'S');
return 0;
}
3.1 Input_connection
/* c语言实现 */
void Input_connection(SetType S)
{
ElementType u, v;
SetName Root1, Root2;
scanf("%d %d\n", &u, &v);
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
if (Root1 != Root2)
Union(S, Root1, Root2);
}
3.2 Check_connection
/* c语言实现 */
void Check_connection(SetType S)
{
ElementType u, v;
scnaf("%d %d\n", &u, &v);
Root1 = Find(S, u-1);
Root2 = Find(S, v-1);
if (Root1 == Root2)
printf("yes\n");
else printf("no\n");
}
3.3 Check_network
/* c语言实现 */
void Check_network(SetType S, int n)
{
int i, counter = 0;
for (i = 0; i < n; i++){
if (S[i] < 0) counter++;
}
if (counter == 1)
printf("The network is connected.\n");
else
printf("There are %d components.\n", counter);
}
四、pta测试
/* c语言实现 */
typedef int ElementType; // 默认元素可以用非负整数表示
typedef int SetName; //默认用根结点的下标作为集合名称
typedef ElementType SetType[MaxSize];
SetName Find(SetType S, ElementType X)
{
// 默认集合元素全部初始化为-1
for (; S[X] >= 0; X = S[X]);
return X;
}
void Union(SetType S, SetName Root1, SetName Root2)
{
// 这里默认Root1和Root2是不同集合的根节点
S[Root2] = Root1;
}
对于上述的代码,如果我们放入pta中测试,会发现测试点6运行超时,如下图所示:
因此,我们会考虑是不是因为出现了某种情况,导致Root2为根结点的树过大了,因此我们修改代码为:
/* c语言实现 */
typedef int ElementType; // 默认元素可以用非负整数表示
typedef int SetName; //默认用根结点的下标作为集合名称
typedef ElementType SetType[MaxSize];
SetName Find(SetType S, ElementType X)
{
// 默认集合元素全部初始化为-1
for (; S[X] >= 0; X = S[X]);
return X;
}
void Union(SetType S, SetName Root1, SetName Root2)
{
// 这里默认Root1和Root2是不同集合的根节点
// S[Root2] = Root1;
S[Root1] = Root2;
}
发现更换代码后,测试点5却运行超时了,为了解决上述问题,我们可以使用下面将要讲到了按秩归并的思想修改代码。
五、按秩归并
为什么需要按秩归并呢?因为我们使用pta测试程序,发现代码总是超时,因此我们可以考虑是否出现这种情况——我们再不断地往一颗树上累加子树,如下图所示:
/* c语言实现 */
Union(Find(2), Find(1));
Union(Find(3), Find(1));
……;
Union(Find(n), Find(1));
从上图可以看出,此过程的时间复杂度为:\(T(n) = O(n^2)\)
除了上述这种情况,会导致树的高度越来越高,如果我们把高树贴在矮树上,那么树高也会快速增长,因此我们应该考虑把矮树贴在高数上。
对于上述问题的解决,我们给出以下两个解决方法,这两种方法统称为按秩归并。
5.1 方法一:树高替代
为了解决上述问题,我们可以把根结点从-1替代为-树高,代码如下:
/* c语言实现 */
if ( Root2高度 > Root1高度 )
S[Root1] = Root2;
else {
if ( 两者等高 ) 树高++;
S[Root2] = Root1;
}
if ( S[Root2] < S[Root1] )
S[Root1] = Root2;
else {
if ( S[Root1]==S[Root2] ) S[Root1]--;
S[Root2] = Root1;
}
5.2 方法二:规模替代
为了解决上述问题,我们也可以把根结点从**-1替代为-元素个数(把小树贴到大树上),代码如下:
/* c语言实现 */
void Union( SetType S, SetName Root1, SetName Root2 )
{
if ( S[Root2]<S[Root1] ){
S[Root2] += S[Root1];
S[Root1] = Root2;
} else {
S[Root1] += S[Root2];
S[Root2] = Root1;
}
}
六、路径压缩
对于上述代码超时的问题,我们也可以使用路径压缩的方法优化代,即压缩给定元素到集合根元素路径中的所有元素,详细情况如下图所示:
上图代码可表示为:
/* c语言实现 */
SetName Find(SetType S, ElementType X)
{
// 找到集合的根
if (S[X] < 0)
return X;
else
return S[X] = Find(S, S[X]);
}
总之上述代码干了这三件事:
- 先找到根;
- 把根变成X的父结点;
- 再返回根
因此,路径压缩第一次执行的时间比较长,但是如果频繁使用查找命令,第一次将路径压缩,大大减小树的高度,后续查找速度将大大增加
6.1 路径压缩时间复杂度计算
由于pta并没有严格控制时间限制,使用java这种语言,不使用路径压缩,问题不大,我写这个也只是为了回顾算法,来放松放松,不是为了折腾自己,因此。
给你一个眼神自己体会,给你一个网址亲自体会https://www.icourse163.org/learn/ZJU-93001?tid=1206471203#/learn/content?type=detail&id=1211167097&sm=1,我是懒得研究下图所示了。
小白专场-FileTransfer-c语言实现的更多相关文章
- 小白专场-多项式乘法与加法运算-c语言实现
目录 一.题意理解 二.求解思路 三.多项式的表示 3.1 数组 3.2 链表 四.程序框架搭建 五.如何读入多项式 六.如何将两个多项式相加 七.如何将两个多项式相乘 八.如何将多项式输出 一.题意 ...
- 小白专场-多项式乘法与加法运算-python语言实现
目录 题意理解 解题思路 多项式加法 多项式乘法 完整代码 题意理解 题目: 设计函数分别求两个一元多项式的乘积与和. 输入格式: 输入分2行,每行分别先给出多项式非零项的个数,再以指数递降方式输入一 ...
- 小白专场-树的同构-c语言实现.md
目录 一.题意理解 二.求解思路 2.1 二叉树表示 2.2 程序框架搭建 2.3 如何建二叉树 2.4 如何判别两二叉树同构 更新.更全的<数据结构与算法>的更新网站,更有python. ...
- 小白专场-是否同一颗二叉搜索树-python语言实现
目录 一.二叉搜索树的相同判断 二.问题引入 三.举例分析 四.方法探讨 4.1 中序遍历 4.2 层序遍历 4.3 先序遍历 4.4 后序遍历 五.总结 六.代码实现 一.二叉搜索树的相同判断 二叉 ...
- 小白专场-树的同构-python语言实现
目录 一.题意理解 二.求解思路 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:<https://www.cnblogs.com/nickch ...
- 小白专场-是否同一颗二叉搜索树-c语言实现
目录 一.题意理解 二.求解思路 三.搜索树表示 程序框架搭建 3.1 如何建搜索树 3.2 如何判别 3.3 清空树 更新.更全的<数据结构与算法>的更新网站,更有python.go.人 ...
- 小白专场-堆中的路径-c语言实现
目录 一.题意理解 二.堆的表示及其操作 三.主程序 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:https://www.cnblogs.com/ ...
- 小白专场-堆中的路径-python语言实现
目录 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11407287.h ...
- 小白专场-FileTransfer-python语言实现
目录 更新.更全的<数据结构与算法>的更新网站,更有python.go.人工智能教学等着你:https://www.cnblogs.com/nickchen121/p/11407287.h ...
随机推荐
- 记录一次Jquery中 this 关键字使用出现的问题
今天在用Jquery改造之前的JS代码过程中,遇到了一个让我懵逼了三小时的问题. 问题的关键在 this 的使用.在这里与大家分享一下.并且分享一下我做表单提交的检查代码 错误代码如下: $(&quo ...
- PicGo+GitHub:你的最佳免费图床选择!
# PicGo介绍 这是一款图片上传的工具,目前支持SM.MS图床,微博图床,七牛图床,腾讯云COS,阿里云OSS,Imgur,又拍云,GitHub等图床,未来将支持更多图床. 所以解决问题的思路就是 ...
- egret之消除游戏开发
1.地图 (1)地图形状不同,尺寸不变 (2)背景图变化 2.步数 (1)不同关卡步数不同 (2)步数为01,游戏失败 3.道具 4.消除 (1)>=3可消除 (2)不可消除时,自动打乱 5.数 ...
- JavaScript中几种常见的兼容问题及解决方案
在js中好用的东西一般都存在兼容问题,以下,我整理了一些常用的兼容处理方法,自己用的时候可以把他们放在一个JS文件中,需要用到时候直接引入,会比较方便. 一.获取非行内样式 function getS ...
- centos6在安装wdcp以后,导入MySQLdb报错问题
为了方便linux的使用,会先安装好wdcp对服务器进行管理.在装好wdcp会对一些nginx,mysql等自动安装,但是mysql的安装目录会在/www/wdlinux这个目录下,跟一般的mysql ...
- Nginx总结(五)如何配置nginx和tomcat实现反向代理
前面讲了如何配置Nginx虚拟主机,大家可以去这里看看nginx系列文章:https://www.cnblogs.com/zhangweizhong/category/1529997.html 今天要 ...
- spring-cloud-kubernetes与SpringCloud Gateway
本文是<spring-cloud-kubernetes实战系列>的第五篇,主要内容是在kubernetes上部署一个SpringCloud Gateway应用,该应用使用了spring-c ...
- ubuntu安装elasticsearch及head插件
1.安装elasticsearch,参考http://www.cnblogs.com/hanyinglong/p/5409003.html就可以了 简单描述下: mkdir -p /usr/local ...
- Python实现 下载IJCAI会议所有论文
import requests import threading def get_file_content(num): savepath = '%04d.pdf' % (num) suburl = ' ...
- 牛客网 Wannafly挑战赛 A 找一找 思考题
链接:https://www.nowcoder.com/acm/contest/71/A来源:牛客网 题目描述 给定n个正整数,请找出其中有多少个数x满足:在这n个数中存在数y=kx,其中k为大于1的 ...