Skip to content

Instantly share code, notes, and snippets.

@garmstro
Created November 9, 2015 22:25
Show Gist options
  • Save garmstro/b3ed86c7532e4d8b22e8 to your computer and use it in GitHub Desktop.
Save garmstro/b3ed86c7532e4d8b22e8 to your computer and use it in GitHub Desktop.
Objective C Initial Binary Tree Implementation
//
// GSABinaryTree.h
// BinaryTree
//
// Created by Geoff Armstrong on 11/3/15.
// Copyright © 2015 Geoff Armstrong. All rights reserved.
//
#ifndef GSABinaryTree_h
#define GSABinaryTree_h
#import "GSABinaryTreeNode.h"
/**
A class representing a binary tree
*/
@interface GSABinaryTree : NSObject
/**
The root node of the binary tree
@return The root node of the binary tree
*/
@property GSABinaryTreeNode *rootNode;
/**
Adds a new node to the binary tree with the specified data
@param data The data represented by the node
*/
- (void) addNodeWithData: (NSObject*) data;
/**
Adds a new node as a left child node of the specified node
@param node The node to add
@param afterNode The parent node of the inserted node
*/
- (void) insertLeftNode: (GSABinaryTreeNode *) node afterNode: (GSABinaryTreeNode *) parentNode;
/**
Adds a new node as a right child node of the specified node
@param node The node to add
@param afterNode The parent node of the inserted node
*/
- (void) insertRightNode: (GSABinaryTreeNode *) node afterNode: (GSABinaryTreeNode *) parentNode;
/**
Finds the maximum depth of the binary tree
@return The maximum depth of the binary tree
*/
- (int) getMaxDepth;
/**
Returns an array containing the left most, then right most alternating values of a binary tree
@return The array containing the left most/right most data
*/
- (NSArray *) treeZigZag;
@end
#endif /* GSABinaryTree_h */
//
// GSABinaryTree.m
// BinaryTree
//
// Created by Geoff Armstrong on 11/3/15.
// Copyright © 2015 Geoff Armstrong. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GSABinaryTree.h"
#import "GSABinaryTreeNode.h"
@implementation GSABinaryTree
- (id) init {
self = [super init];
if (self) {
_rootNode = nil;
}
return self;
}
- (void) addNodeWithData:(NSObject *)data {
if (!self.rootNode) {
self.rootNode = [GSABinaryTreeNode nodeWithData:data];
}
else {
GSABinaryTreeNode *newNode = [GSABinaryTreeNode nodeWithData:data];
[[self rootNode] addNode: newNode];
}
}
- (void) insertLeftNode:(GSABinaryTreeNode *)node afterNode:(GSABinaryTreeNode *)parentNode {
if (parentNode.leftNode) {
node.leftNode = parentNode.leftNode;
node.leftNode.parentNode = node;
}
parentNode.leftNode = node;
node.parentNode = parentNode;
}
- (void) insertRightNode:(GSABinaryTreeNode *)node afterNode:(GSABinaryTreeNode *)parentNode {
if (parentNode.rightNode) {
node.rightNode = parentNode.rightNode;
node.rightNode.parentNode = node;
}
parentNode.rightNode = node;
node.parentNode = parentNode;
}
- (int) getMaxDepth {
if (self.rootNode) {
return [self.rootNode getMaxDepth:0];
}
else {
return 0;
}
}
/**
There has got to be a better way to do this!
*/
- (NSArray *) treeZigZag {
NSMutableArray *theArray = [NSMutableArray arrayWithObject:self.rootNode.data];
GSABinaryTreeNode *leftMostNode = self.rootNode;
if (self.rootNode.leftNode) {
leftMostNode = self.rootNode.leftNode;
}
else {
leftMostNode = self.rootNode.rightNode;
}
GSABinaryTreeNode *rightMostNode = self.rootNode;
BOOL isRightDone = NO;
BOOL isLeftDone = NO;
while (isRightDone != YES && isLeftDone != YES) {
//Get the rightmost node
if (!rightMostNode.rightNode && !rightMostNode.leftNode) {
isRightDone = YES;
}
else if (rightMostNode.rightNode) {
[theArray addObject:rightMostNode.rightNode.data];
if (rightMostNode.rightNode.rightNode) {
rightMostNode = rightMostNode.rightNode.rightNode;
}
else {
rightMostNode = rightMostNode.rightNode.leftNode;
}
}
else {
[theArray addObject:rightMostNode.leftNode.data];
if (rightMostNode.leftNode.rightNode) {
rightMostNode = rightMostNode.leftNode.rightNode;
}
else {
rightMostNode = rightMostNode.leftNode.leftNode;
}
}
//Get the leftmost node
if (!leftMostNode.leftNode && !leftMostNode.rightNode) {
isLeftDone = YES;
}
else if (leftMostNode.leftNode) {
[theArray addObject:leftMostNode.leftNode.data];
if (leftMostNode.leftNode.leftNode) {
leftMostNode = leftMostNode.leftNode.leftNode;
}
else {
leftMostNode = leftMostNode.leftNode.rightNode;
}
}
else {
[theArray addObject:leftMostNode.rightNode.data];
if (leftMostNode.rightNode.leftNode) {
leftMostNode = leftMostNode.rightNode.leftNode;
}
else {
leftMostNode = leftMostNode.rightNode.rightNode;
}
}
}
return theArray;
}
@end
//
// GSABinaryTreeNode.h
// BinaryTree
//
// Created by Geoff Armstrong on 11/3/15.
// Copyright © 2015 Geoff Armstrong. All rights reserved.
//
#ifndef GSABinaryTreeNode_h
#define GSABinaryTreeNode_h
/**
A class representing a node of a binary tree
*/
@interface GSABinaryTreeNode : NSObject
/**
The parent node in the binary tree
@return The node's parent
*/
@property (weak) GSABinaryTreeNode *parentNode;
/**
The left child node
@return The node's left child
*/
@property GSABinaryTreeNode *leftNode;
/**
The right child node
@return The node's right child
*/
@property GSABinaryTreeNode *rightNode;
/**
The node's data
@return data represented by the node
*/
@property NSObject *data;
/**
Allocates and initializes a node with the supplied data
@param data The node data
@return The allocated and initialized node
*/
+ (instancetype) nodeWithData: (NSObject *) data;
/**
Initializes a node with the supplied data
@param data The node data
@return The initialized node
*/
- (id) initNodeWithData: (NSObject *) data;
/**
Adds a child node to the node, if a spot is available
@param node The node to add to the tree
*/
- (void) addNode: (GSABinaryTreeNode *) node;
/**
Finds the maximum depth from the current node
@param depth The initial depth of the current node
@return The maximum depth from the current node
*/
- (int) getMaxDepth: (int) depth;
@end
#endif /* GSABinaryTreeNode_h */
//
// GSABinaryTreeNode.m
// BinaryTree
//
// Created by Geoff Armstrong on 11/3/15.
// Copyright © 2015 Geoff Armstrong. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "GSABinaryTreeNode.h"
@interface GSABinaryTreeNode ()
@property (readwrite) BOOL flipper;
@end
@implementation GSABinaryTreeNode
+ (instancetype) nodeWithData: (NSObject *) theData {
GSABinaryTreeNode *newNode = [[GSABinaryTreeNode alloc] initNodeWithData:theData];
return newNode;
}
- (id) initNodeWithData: (NSObject *) theData {
self = [super init];
if (self) {
_data = theData;
_leftNode = nil;
_rightNode = nil;
_flipper = NO;
}
return self;
}
- (void) addNode: (GSABinaryTreeNode *) theNode {
if (![self leftNode]) {
theNode.parentNode = self;
self.leftNode = theNode;
}
else if (![self rightNode]) {
theNode.parentNode = self;
self.rightNode = theNode;
}
else {
if (!self.flipper) {
self.flipper = !self.flipper;
[[self leftNode] addNode: theNode];
}
else {
self.flipper = !self.flipper;
[[self rightNode] addNode: theNode];
}
}
}
- (int) getMaxDepth:(int)depth {
//If neither left nor right exist this is a leaf node
if (!self.leftNode && !self.rightNode) {
return ++depth;
}
//If rightNode exists, find depth of right node
else if (!self.leftNode && self.rightNode) {
++depth;
return [[self rightNode] getMaxDepth:depth];
}
//If left node exists, find depth of left node
else if (self.leftNode && !self.rightNode) {
++depth;
return [[self leftNode] getMaxDepth:depth];
}
//If both exist, return the max depth of both nodes
else {
++depth;
int leftDepth = [[self leftNode] getMaxDepth:depth];
int rightDepth = [[self rightNode] getMaxDepth:depth];
return ( leftDepth >= rightDepth ) ? leftDepth : rightDepth;
}
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment