Skip to content

Commit

Permalink
initialize
Browse files Browse the repository at this point in the history
  • Loading branch information
周井江-技术中心-服务研发部 committed Sep 1, 2017
1 parent f6c55ed commit 70d0840
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 0 deletions.
95 changes: 95 additions & 0 deletions 树/树与等价关系/MFSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import java.util.*;

class Node<T> {
public static class Entry<T> {
public Node<T> node;
public int index;

@Override
public String toString() {
String nodeString = "null";
if (node != null)
nodeString = node.toString();
return String.format("Entry{node=%s, index=%d}", nodeString, index);
}
}

private T element;
private int parent;

public Node(T element) {
this(element, -1);
}

public Node(T element, int parent) {
this.element = element;
this.parent = parent;
}


public T getElement() {
return element;
}

public int getParent() {
return parent;
}

public void setParent(int parent) {
this.parent = parent;
}

public Entry<T> findRoot(List<Node<T>> nodes) {
Entry<T> entry = new Entry<>();
entry.index = nodes.indexOf(this);
entry.node = this;

Node<T> node = this;
while (node.getParent() >= 0) {
entry.index = node.getParent();
entry.node = node = nodes.get(entry.index);
}
return entry;
}

public void merge(Node<T> anotherNode, List<Node<T>> nodes) {
Entry<T> anotherEntry = anotherNode.findRoot(nodes);
Entry<T> entry = this.findRoot(nodes);
if (anotherEntry.node == entry.node)
return;

int anotherCount = -1 * anotherEntry.node.getParent();
int count = -1 * entry.node.getParent();

if (anotherCount > count) {
entry.node.setParent(anotherEntry.index);
anotherEntry.node.setParent(-1*(anotherCount + count));
} else {
anotherEntry.node.setParent(entry.index);
entry.node.setParent(-1*(anotherCount + count));
}
}

@Override
public String toString() {
return String.format("Node{element=%s, parent=%d}",
element.toString(), parent);
}
}

public class MFSet {
public static void main(String[] args) {
List<Node<Integer>> nodes = new ArrayList<>();
for (int i = 0; i < 9; i++)
nodes.add(new Node(i));
int[][] R = new int[][]{new int[]{0, 2}, new int[]{2, 4},
new int[]{4, 6}, new int[]{6, 8}};

for (int[] pair: R) {
nodes.get(pair[0]).merge(nodes.get(pair[1]), nodes);
}

System.out.println(nodes);
}
}

55 changes: 55 additions & 0 deletions 树/树与等价关系/MFSet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
class Node:
def __init__(self, element, parent=-1):
self._element = element
self._parent = parent

def set_parent(self, parent):
self._parent = parent

def get_parent(self):
return self._parent

def get_element(self):
return self._element

def find_root(self, nodes):
index = nodes.index(self)
node = self
while node.get_parent() >= 0:
index = node.get_parent()
node = nodes[index]
return node, index

def merge(self, another, nodes):
another_root, another_index = another.find_root(nodes)
root, index = self.find_root(nodes)
if another_root == root:
return

another_nodes_count = -1 * another_root.get_parent()
nodes_count = -1 * root.get_parent()

if another_nodes_count > nodes_count:
root.set_parent(another_index)
another_root.set_parent(-1*(another_nodes_count + nodes_count))
else:
another_root.set_parent(index)
root.set_parent(-1*(another_nodes_count + nodes_count))

def __str__(self):
return "Node[element={0._element}, parent={0._parent}]".format(self)
__repr__ = __str__

def main():
R = [(0, 2), (2, 4), (4, 6), (6, 8)]
S = [0, 1, 2, 3, 4, 5, 6, 7, 8]
nodes = [Node(element, -1) for element in S]

for x, y in R:
nodes[x].merge(nodes[y], nodes)

print nodes

if __name__ == "__main__":
main()

23 changes: 23 additions & 0 deletions 树/树与等价关系/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h3>等价关系</h3>
设R是非空集合S上的二元关系,如果R是<strong>自反的</strong>、<strong>对称的</strong>、<strong>传递的</strong>,则称R是S上的等价关系。</br>
<ul>
<li><strong>自反性</strong>:如果元素a属于集合S,则(a, a)属于R</br>∀ a ∈ S =&gt; (a, a) ∈ R</li>
<li><strong>对称性</strong>:如果(a, b)属于R,且a不等于b,则(b, a)属于R</br>(a, b) ∈ R ∧ a ≠ b =&gt; (b, a) ∈ sR</li>
<li><strong>传递性</strong>:如果(a, b)属于R,(b, c)属于R,则(a, c)属于R</br>(a, b) ∈ R, (b, c) ∈ R =&gt; (a, c) ∈ R</li>
</ul>
如果(a, b) ∈ R,则称a和b是等价的,记作 a ~ b。</br>
比如,同班同学 和 同乡 是等价关系;相似三角形 和 全等三角形 是等价关系。。。
<hr></hr>
<h3>树的双亲表示法</h3>
用一个<em>链表</em>存储树的每一个结点;每个结点包含两个域:数据域---用来保存数据,指针域---用来指示双亲节点在链表中的索引。</br>
因为根节点没有双亲节点,所以根节点的指针域的值是负的,可以利用这个负值来表示,树中节点的数量。</br>
在双亲表示法中,便于寻找根节点 和 父节点。但是寻找子节点需要遍历所有节点。
<hr></hr>
<h3>如何划分等价类</h3>
按R将S划分成若干个不相交的子集S1,S2,。。。,Sn(它们的并集是S),则称这些子集是S的<strong>等价类</strong>。</br>
假设集合S有n个元素,m个形如(x, y)(x, y ∈ S)的<strong>等价偶对</strong>确定了等价关系R。则将S划分成等价类的算法是:</br>
<ul>
<li>令集合S中的每个元素 各自 形成一个只包含单个结点的子集,记作S1,S2。。。Sn</li>
<li>依次读入m个等价偶对,对于每一个偶对(x, y),设x属于S<sub>i</sub>,y属于S<sub>j</sub>,当S<sub>i</sub>不等于S<sub>j</sub>时,可以将S<sub>i</sub>合并到S<sub>j</sub>,并将S<sub>i</sub>置空(也可以将S<sub>j</sub>合并到S<sub>i</sub>,并将S<sub>j</sub>置空)</li>
</ul>
<strong><em>值得注意的是:在进行合并的时候,如果总是将节点多的树合并到节点少的树,会导致树的高度变大,进而导致 寻找节点所属的树的根节点的时候,时间会增大。</em>因此,在合并的时候,选择将节点少的树合并到节点多的树,并且利用根节点的游标域保存该棵树的节点数量的负值。</strong>

0 comments on commit 70d0840

Please sign in to comment.