You are on page 1of 5

Homework - Week 13

Name:RAHMAN MD MATIUR
Student Id :2230130236
Please watch these videos first, and finish your homework after class. You can edit
WORD documents directly, or take photos after writing them down, and send them to my
email. My email: xupeng.01@163.com
If you can't do some problems in your homework, you can leave it blank.
请大家先认真学习视频,再完成下列作业。作业可以直接编辑 Word 文档,也可
以写下后拍照,将文档或照片发我的电子邮箱。我的邮箱:xupeng.01@163.com
如果作业中有些题目不会,可以空着不做。

Task 1: Describe two ways to implement disjoint sets.(请描述实现不相交集的两种方


法。)
Answer:

1.Array-Based Implementation: One way to implement disjoint sets is by using an


array-based approach. In this method, each element in the array represents a set, and
the value at each index represents the parent of that element. Initially, all elements are
considered as separate sets, so each element is its own parent.

To perform the union operation, you need to find the roots of the sets to which the
elements belong and make one of the roots the parent of the other. This effectively
merges the two sets. You can use techniques like path compression to optimize the find
operation, where you recursively update the parent of each element along the path to
the root to directly point to the root.

Here's a simple example implementation in Python:

class DisjointSet:
def __init__(self, size):
self.parent = list(range(size))

def find(self, element):


if self.parent[element] != element:
self.parent[element] = self.find(self.parent[element])
return self.parent[element]

def union(self, element1, element2):


root1 = self.find(element1)
root2 = self.find(element2)
if root1 != root2:
self.parent[root2] = root1

2.Tree-Based Implementation (Rank-Union): Another way to implement disjoint sets is


using a tree-based approach, specifically the rank-union method. In this approach, each
element is represented as a node in a tree structure. The tree's root represents the set,
and each node's parent points to its parent node.
Initially, each element is a separate tree. To perform the union operation, you compare
the ranks (or heights) of the two trees and make the tree with the smaller rank a child of
the tree with the larger rank. This helps to keep the tree balanced and ensures efficient
find and union operations.

Here's a simplified implementation in Python


class DisjointSet:
def __init__(self, size):
self.parent = list(range(size))
self.rank = [0] * size

def find(self, element):


if self.parent[element] != element:
self.parent[element] = self.find(self.parent[element])
return self.parent[element]

def union(self, element1, element2):


root1 = self.find(element1)
root2 = self.find(element2)
if root1 != root2:
if self.rank[root1] < self.rank[root2]:
self.parent[root1] = root2
elif self.rank[root1] > self.rank[root2]:
self.parent[root2] = root1
else:
self.parent[root2] = root1
self.rank[root1] += 1

These are two common ways to implement disjoint sets. The choice of implementation
depends on factors like the specific requirements, the size of the sets, and the expected
operations' frequency.

Task 2:Which one to hang when merging two trees?(当合并两棵树时,将哪棵树悬挂


于另一棵上?)
Answer:

When merging two trees, the decision of which tree to hang, or attach, to the other
depends on the specific context and requirements of the merging operation. The term
"hanging" typically refers to attaching one tree as a subtree to another tree.

Here are a few common approaches to merging trees:

Attach one tree as a child/subtree of the other: In this approach, we can choose one tree
as the primary or parent tree and attach the other tree as a child or subtree. The choice
of the parent tree depends on the desired structure and hierarchy. If one tree is
considered the main or dominant tree, it can serve as the parent, and the other tree can
be attached as a child or subtree.
Combine trees by creating a new root: In some cases, we might want to create a new
root node and make both trees children of that new root. This approach is useful when
the merged trees do not have a clear hierarchical relationship, and we want to maintain
both trees as separate branches.

Merge trees as siblings: If the two trees have a similar structure and we want to merge
them as siblings, we can attach one tree as a sibling to the root or any other node of the
other tree. This approach can be useful when we want to combine trees that represent
different branches or variations of the same structure.

Ultimately, the decision of which tree to hang or how to merge them depends on the
specific requirements and constraints of our application or problem domain. Consider
the intended structure, relationships between the trees, and the purpose of the merging
operation to determine the most appropriate approach.

Task 3:How to implement path compression?(如何实现路径压缩?)


Answer:

Path compression is a technique used in disjoint-set data structures, specifically in the


context of union-find operations. It helps optimize the efficiency of these operations by
compressing the paths between nodes in the tree structure.
Here's a step-by-step guide on how to implement path compression in a union-find data
structure:

Define the data structure: Start by defining the data structure for representing the
disjoint sets. Each element in the set will have a parent pointer that initially points to
itself. Additionally, we can have a rank or size value to optimize the union operation
(e.g., by merging the smaller set into the larger set).

Implement the find operation: The find operation is used to determine the
representative (root) element of a given set. It follows the parent pointers until it
reaches the root element. Along the way, it can perform path compression to optimize
future find operations.

Start by recursively calling the find operation on the parent of the current element.

Once the root element is found, set the parent pointer of all elements on the path from
the current element to the root element to point directly to the root. This is the path
compression step.

Return the root element as the representative of the set.

Here is an example implementation in python:


def find(parent, x):
if parent[x] != x:
parent[x] = find(parent, parent[x]) # path compression
return parent[x]
Implement the union operation: The union operation merges two sets together. To
optimize this operation, we can use the rank or size information to decide which set
should be merged into the other.

Find the representatives (roots) of the sets containing the two elements to be united.

If the representatives are the same, the elements are already in the same set, and no
further action is needed.

Otherwise, compare the ranks (or sizes) of the two representatives to determine the
merging order.

Update the parent pointer of the representative with the smaller rank (or size) to point
to the representative with the larger rank (or size).

Here's an example implementation in Python:

def union(parent, rank, x, y):


x_root = find(parent, x)
y_root = find(parent, y)

if x_root == y_root:
return

if rank[x_root] < rank[y_root]:


parent[x_root] = y_root
elif rank[x_root] > rank[y_root]:
parent[y_root] = x_root
else:
parent[y_root] = x_root
rank[x_root] += 1

With these steps, we can implement path compression in a union-find data structure. By
applying path compression during find operations, we can achieve nearly constant time
complexity for subsequent find operations, improving the overall efficiency of the
disjoint-set data structure.

Task 4:If using path compression, rank[i] is equal to the height of the tree rooted at i.
Yes or No

Answer:

No, that statement is not accurate.

In the context of path compression in disjoint-set data structures (such as the Union-
Find data structure), the rank of a node is not equal to the height of the tree rooted at
that node. The rank represents an upper bound on the height of the node's subtree, but
it is not necessarily equal to the exact height.
The purpose of path compression is to optimize the performance of the Union-Find data
structure by making the paths from a node to its root as short as possible. When
performing a find operation (which determines the root of a given node), path
compression flattens the tree by making each node on the path point directly to the root,
reducing the height of the tree.

By applying path compression, the rank of a node may change during the path
compression process. The rank is typically used to decide which tree should be the root
when performing a union operation (i.e., merging two disjoint sets). The tree with the
smaller rank is attached to the root of the tree with the larger rank, which helps to keep
the overall height of the resulting tree smaller and ensures efficient subsequent find
operations.

So, to summarize, while path compression helps to reduce the height of trees in a Union-
Find data structure, the rank of a node is not equal to the height of the tree rooted at
that node. The rank is an approximation of the height and is used for optimization
purposes in union operations.

You might also like