2020-07-25- 第八周作业

用户头像
路易斯李李李
关注
发布于: 2020 年 07 月 26 日

作业一

有两个单向链表(链表长度分别为m,n),这两个单向链表有可能在某个元素合并,也可能不合并,如下图所示。现在给定两个链表的头指针,在不修改链表的情况下,如何快速地判断这两个链表是否合并?如果合并,找到合并的元素,也就是图中的x元素。



请用代码(或伪代码)描述算法,并给出时间复杂度和空间复杂度。

答:

使用java代码实现该算法,具体代码如下



/**
* 链表合并算法
* @param headA 链表A
* @param headB 链表B
* @return
*/
private static String merge(Node headA, Node headB) {
int m = size(headA); // A的长度
int n = size(headB); // B的长度
int offset = n - m; // 计算A与B的长度差值
Node A = headA;
Node B = headB;
if(m > n) {
A = headB;
B = headA; // 始终保持Node A的长度小于Node B
offset = m - n;
}
while(offset > 0) { // 遍历B,直到B的剩余长度与A相同
B = B.next;
offset--;
}
String res = null; // 首个相同元素的值
while(A.next!=null) {
if(A.equals(B)) {
if(res == null) { // 同时遍历A和B,如果a==b并且res不为空,则设置res为a
res = A.elem;
}
} else {
res = null; // 一旦接下来有不相同的元素则置res为null
}
A = A.next;
B = B.next;
}
return res;
}



// 链表结点结构类
public class Node {
String elem;
public Node next;
public Node(){}
public Node(String elem) {
this.elem = elem;
}
public boolean equals(Node B) {
return B!=null && this.elem!=null && this.elem.equals(B.elem);
}
}



/**
* 计算链表大小
* @param headA
* @return
*/
private static int size(Node headA) {
int size = 0;
Node rnode = headA;
while(rnode.next!=null) {
rnode = rnode.next;
size++;
}
return size;
}

可以从merge方法中看出,计算A和B的长度需要耗费m+n,遍历B的前部分需要m-n,遍历A和B则需要n。所以最终时间复杂度为O(2n)。



作业二

请画出DataNode服务器节点宕机的时候,HDFS的处理过程时序图。

答:

DataNode服务器节点宕机后的处理过程如下:

(1)宕机的DataNodeA节点停止向NameNode发送心跳,当心跳超时后,NameNode判定这个DataNode已宕机。

(2)NameNode通过自身节点的元数据,查询到存储在DataNodeA上的数据块集合S。同时找出备份这些数据块的服务器DataNodeMi(其中i为1,2,...n),其中Mi上存储的数据块集合为Si,且满足S = S1 + S2 +... + Sn。

(3)接着NameNode向备份服务器DataNodeMi发送指令,通知其将自身的数据块集合Si,同步一份到其余集群中的一台DataNodeNi(其中i为1,2,...n)。

(4)最后DataNodeMi将自身数据块集合Si同步到集群中另一台DataNodeNi节点上,最终使得每个数据块在3个节点上均有备份。

(5)当数据块同步完成后,DataNodeNi将自身数据块信息通知NameNode,以便NameNode更新元数据。

下图为DataNode服务器节点宕机后的处理时序图。



用户头像

路易斯李李李

关注

还未添加个人签名 2020.05.11 加入

还未添加个人简介

评论

发布
暂无评论
2020-07-25-第八周作业