-
Notifications
You must be signed in to change notification settings - Fork 0
/
union-find-set.js
169 lines (158 loc) · 3.7 KB
/
union-find-set.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* quick find
*
* 结构:[0, 4, 4, 4, 4, 5, 6, 7, 8, 9]
*
* 初始化阶段:
* 0,1,2,3,4,5,6,7,8,9(数据)
* --------------------
* 0,1,2,3,4,5,6,7,8,9(集合id)
*
* 一系列合并操作后:
* 0,1,2,3,4,5,6,7,8,9(数据)
* --------------------
* 0,4,4,4,4,5,6,7,8,9(集合id)
*
* 如上:数据1,2,3,4同属一个集合
*/
class QuickFind {
/**
* Initialize your data structure here. Set the size of the QuickFind to be size.
* @param {number} size
*/
constructor(size) {
this.ids = []
for (let i = 0; i < size; i++) {
this.ids[i] = i
}
}
/**
* Finds an item from QuickFind. Return the value if the operation is successful.
* @param {number} index
* @return {number}
*/
find = index => {
return this.ids[index]
}
/**
* Return the true if two params is connected.
* @param {number} p
* @param {number} q
* @return {boolean}
*/
isConnected = (p, q) => {
return this.ids[p] === this.ids[q]
}
/**
* Merge the two params. Return true if the operation is successful.
* @param {number} p
* @param {number} q
* @return {boolean}
*/
union(p, q) {
if (this.isConnected(p, q)) return false
let pId = this.find(p),
qId = this.find(q)
for (let i = 0; i < this.ids.length; i++) {
if (pId === this.ids[i]) this.ids[i] = qId
}
return true
}
/**
* Return the length of the QuickFind.
* @return {number}
*/
sizeOfElement() {
return this.ids.length
}
}
// 测试代码
// const test = new QuickFind(10)
// test.find(5)
// test.union(3, 4)
// test.union(3, 4)
/**
* quick union --- 秩合并优化
*
* //每个节点本身有一个指针,指向另一个元素
* //数组存放的就是指针
* 结构:[0, 2 , 3 , 4 , 4, 5, 6, 7, 8, 9]
*
* 初始化阶段:
* 0,1,2,3,4,5,6,7,8,9(数据)
* --------------------
* 0,1,2,3,4,5,6,7,8,9(集合id)
*
* 一系列合并操作后:
* 0,1,2,3,4,5,6,7,8,9(数据)
* -------------------------
* 0,2,3,4,4,5,6,7,8,9(集合id)
* 如上:2表示第二个元素所在的节点指向了2这个元素
* 数据1,2,3,4同属一个集合
*/
class QuickUnion {
/**
* Initialize your data structure here. Set the size of the QuickFind to be size.
* @param {number} size
*/
constructor(size) {
this.ids = []
this.branch = []
for (let i = 0; i < size; i++) {
this.ids[i] = i
this.branch[i] = 1
}
}
/**
* Finds an item from QuickFind. Return the value if the operation is successful.
* @param {number} index
* @return {number}
*/
find = index => {
if (index < 0 || index >= this.ids.length) return -1
while (index !== this.ids[index]) index = this.ids[index]
return index
}
/**
* Return true if two params is connected.
* @param {number} p
* @param {number} q
* @return {boolean}
*/
isConnected = (p, q) => {
let pId = this.find(p),
qId = this.find(q)
if (pId === -1 || qId === -1) return false
return pId === qId
}
/**
* Merge the two params. Return true if the operation is successful.
* @param {number} p
* @param {number} q
* @return {boolean}
*/
union(p, q) {
let pId = this.find(p),
qId = this.find(q)
if (pId === -1 || qId === -1 || pId === qId) return false
if (this.branch[pId] >= this.branch[qId]) {
this.ids[qId] = pId
this.branch[pId] += this.branch[qId]
} else {
this.ids[pId] = qId
this.branch[qId] += this.branch[pId]
}
return true
}
/**
* Return the length of the QuickFind.
* @return {number}
*/
sizeOfElement() {
return this.ids.length
}
}
// const test = new QuickUnion(6)
// test
// test.find(3)
// test.union(0, 3)