1. How would you copy a custom object like a "Node" from a search tree in Objective C?
Version 1
@interface Node : NSObject <NSCopying>
@end
@implementation Node
- (id) copyWithZone: (NSZone*)zone {
id copy = [[[self class] alloc] init];
if (copy) {
[copy setVal: self.val];
[copy setRootNode: [[self.rootNode copyWithZone:zone]]];
[copy setLeftNode: [[self.leftNode copyWithZone:zone]]];
[copy setRightNode: [[self.rightNode copyWithZone:zone]]];
}
return copy;
}
@end
//Now you can do something like:
Node* myNode = [[Node alloc] init];
Node* newNode = [myNode copy];
Version 2
https://gist.github.com/zats/c075815e1fa24b001fb2
// Node.h
#import <Foundation/Foundation.h>
@interface Node : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, weak, readonly) Node *parent;
@property (nonatomic, strong, readonly) Node *left;
@property (nonatomic, strong, readonly) Node *right;
- (instancetype)initWithParent:(Node *)parent left:(Node *)left right:(Node *)right;
@end
@interface MutableNode : Node
@property (nonatomic, weak) Node *parent;
@property (nonatomic, strong) Node *left;
@property (nonatomic, strong) Node *right;
@end
// Node.m
#import "Node.h"
@interface Node ()
@property (nonatomic, weak) Node *parent;
@property (nonatomic, strong) Node *left;
@property (nonatomic, strong) Node *right;
@end
@implementation Node
- (instancetype)initWithParent:(Node *)parent left:(Node *)left right:(Node *)right {
self = [super init];
if (!self) {
return nil;
}
self.parent = parent;
self.left = left;
self.right = right;
return self;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)mutableCopyWithZone:(NSZone *)zone {
MutableNode *node = [[MutableNode allocWithZone:zone] init];
node.parent = self.parent;
node.left = self.left;
node.right = self.right;
return node;
}
- (void)setLeft:(Node *)left {
_left = left;
if (left.parent != self) {
left.parent = self;
}
}
- (void)setRight:(Node *)right {
_right = right;
if (right.parent != self) {
right.parent = self;
}
}
- (NSString *)description {
NSMutableString *string = [NSMutableString stringWithFormat:@"<%@:%p>", [self class], self];
if (!self.parent && !self.left && !self.right) {
return [string copy];
}
[string appendString:@" {"];
if (self.parent) {
[string appendFormat:@" parent = <%@:%p>", [self.parent class], self.parent];
}
if (self.left) {
[string appendFormat:@" left = <%@:%p>", [self.left class], self.left];
}
if (self.right) {
[string appendFormat:@" right = <%@:%p>", [self.right class], self.right];
}
[string appendString:@" }"];
return [string copy];
}
@end
@implementation MutableNode
- (id)copyWithZone:(NSZone *)zone {
Node *node = [[Node allocWithZone:zone] init];
[node setValue:self.parent forKey:@"parent"];
[node setValue:self.left forKey:@"left"];
[node setValue:self.right forKey:@"right"];
return node;
}
@end
2. Inorder Enum Binary Tree
+ (void) inorderTraversal:(TreeNode*) root block:(void(^)(NSString*))block {
[self inorderTraversal:root.left block:block];
block(root.val);
[self inorderTraversal:root.right block:block];
}
// use
NSMutableArray* res = [NSMutableArray array];
int (^readingBlock)(NSString*) = ^(NSString* cur) {
[res addObject:cur];
};
+ (void) inorderTraversal:(TreeNode*) root array:(NSMutableArray*)array {
[self inorderTraversal:root.left block:block];
[array addObject:root.val];
[self inorderTraversal:root.right block:block];
}