これは、素集合の私の Objective-C 実装です。- 親への正数ポイント。- 負の数は、ルートと子の数を示します。(したがって、それらはそれぞれ -1 でバラバラに開始します。) - インデックスは、グループ化するデータとして機能します。問題ないようです... いくつか質問がありました。
find:パスを圧縮するにはどうすればよいですか? 私は再帰的に行っていないので、ルートを見つけた後に設定するために、パスを保存して再度ループする必要がありますか?
join: 深さではなく、子の数に基づいて結合しています!? それは正しくないと思います。深さが等しい場合、結合中に何か特別なことをする必要がありますか?
ありがとう。
DisjointSet.h
@interface DisjointSet : NSObject
{
NSMutableArray *_array;
}
- (id)initWithSize:(NSInteger)size;
- (NSInteger)find:(NSInteger)item;
- (void)join:(NSInteger)root1 root2:(NSInteger)root2;
@end
DisjointSet.m
#import "DisjointSet.h"
@implementation DisjointSet
- (id)initWithSize:(NSInteger)size
{
self = [super init];
if (self)
{
_array = [NSMutableArray arrayWithCapacity:size];
for (NSInteger i = 0; i < size; i++)
{
[_array addObject:[NSNumber numberWithInteger:-1]];
}
}
return self;
}
- (NSInteger)find:(NSInteger)item
{
while ([[_array objectAtIndex:item] integerValue] >= 0)
{
item = [[_array objectAtIndex:item] integerValue];
}
return item;
}
- (void)join:(NSInteger)root1 root2:(NSInteger)root2
{
if (root1 == root2) return;
NSInteger data1 = [[_array objectAtIndex:root1] integerValue];
NSInteger data2 = [[_array objectAtIndex:root2] integerValue];
if (data2 < data1)
{
[_array setObject:[NSNumber numberWithInteger:data2 + data1] atIndexedSubscript:root2];
[_array setObject:[NSNumber numberWithInteger:root2] atIndexedSubscript:root1];
}
else
{
[_array setObject:[NSNumber numberWithInteger:data1 + data2] atIndexedSubscript:root1];
[_array setObject:[NSNumber numberWithInteger:root1] atIndexedSubscript:root2];
}
}
@end