Last active
December 17, 2024 01:43
-
-
Save mthomason/c57ece8f5f8e1304fa1048dd8b1f61fe to your computer and use it in GitHub Desktop.
Objective-C Linked List
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MNLinkedList.h | |
// libMTDataStrutures | |
// | |
// Created by Michael Thomason on 12/10/12. | |
// Copyright © 2024 Michael Thomason. All rights reserved. | |
// | |
#ifndef MAD_DataStructures_MTLinkedList_h | |
#define MAD_DataStructures_MTLinkedList_h | |
#import <Foundation/NSObject.h> | |
#import <Foundation/NSEnumerator.h> | |
#ifndef NS_DESIGNATED_INITIALIZER | |
#if __has_attribute(objc_designated_initializer) | |
#define NS_DESIGNATED_INITIALIZER __attribute((objc_designated_initializer)) | |
#else | |
#define NS_DESIGNATED_INITIALIZER | |
#endif | |
#endif | |
@interface MTLinkedList : NSObject <NSFastEnumeration> | |
- (instancetype)init NS_DESIGNATED_INITIALIZER; | |
- (NSUInteger)count; | |
- (void)insert:(id)object; | |
- (void)add:(id)object; | |
- (id)head; | |
- (id)getNext; | |
- (id)getPrevious; | |
- (id)getTop; | |
- (id)getBottom; | |
- (BOOL)isNext; | |
- (BOOL)isPrevious; | |
- (id)objectAtIndex:(NSUInteger)index; | |
- (void)reverse; | |
- (NSArray *)toArray; | |
@end | |
#endif |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MNLinkedList.m | |
// libMTDataStrutures | |
// | |
// Created by Michael Thomason on 12/10/12. | |
// Copyright © 2024 Michael Thomason. All rights reserved. | |
// | |
#if ! __has_feature(objc_arc) | |
#warning Compile this file with ARC using the -fobjc-arc flag. | |
#endif | |
#import "MTLinkedList.h" | |
#import <Foundation/NSArray.h> | |
#import <Foundation/NSString.h> | |
#import "MTLinkedListNode.h" | |
@interface MTLinkedList () | |
@property (nonatomic, strong) MTLinkedListNode *headNode; | |
@property (nonatomic, strong) MTLinkedListNode *tailNode; | |
@property (nonatomic) NSUInteger count; | |
@property (nonatomic, weak) MTLinkedListNode *currentNode; | |
@end | |
@implementation MTLinkedList | |
- (instancetype)init { | |
if (self = [super init]) { | |
_headNode = nil; | |
_tailNode = nil; | |
_currentNode = nil; | |
_count = 0; | |
} | |
return self; | |
} | |
- (void)insert:(id)object { | |
if (!object) return; | |
MTLinkedListNode *newNode = [[MTLinkedListNode alloc] initWithData:object]; | |
if (!_headNode) { | |
_headNode = _tailNode = newNode; | |
} else { | |
newNode.next = _headNode; | |
_headNode.prev = newNode; | |
_headNode = newNode; | |
} | |
_count++; | |
} | |
- (void)add:(id)object { | |
if (!object) return; | |
MTLinkedListNode *newNode = [[MTLinkedListNode alloc] initWithData:object]; | |
if (!_tailNode) { | |
_headNode = _tailNode = newNode; | |
} else { | |
newNode.prev = _tailNode; | |
_tailNode.next = newNode; | |
_tailNode = newNode; | |
} | |
_count++; | |
if (!_currentNode) { | |
_currentNode = _headNode; | |
} | |
} | |
- (id)head { | |
return _headNode ? _headNode.data : nil; | |
} | |
- (id)getNext { | |
MTLinkedListNode *strongCurrentNode = _currentNode; | |
if (!strongCurrentNode) { | |
_currentNode = _headNode; | |
strongCurrentNode = _headNode; | |
} | |
if (strongCurrentNode && strongCurrentNode.next) { | |
_currentNode = strongCurrentNode.next; | |
MTLinkedListNode *resultNode = _currentNode; | |
return resultNode.data; | |
} | |
return nil; | |
} | |
- (id)getPrevious { | |
MTLinkedListNode *strongCurrentNode = _currentNode; | |
if (strongCurrentNode && strongCurrentNode.prev) { | |
MTLinkedListNode *strongPrevNode = strongCurrentNode.prev; | |
_currentNode = strongPrevNode; | |
return strongPrevNode.data; | |
} | |
return nil; | |
} | |
- (id)getTop { return _headNode ? _headNode.data : nil; } | |
- (id)getBottom { return _tailNode ? _tailNode.data : nil; } | |
- (BOOL)isNext { | |
MTLinkedListNode *strongCurrentNode = _currentNode; | |
if (!strongCurrentNode) { | |
return _headNode != nil; | |
} | |
return strongCurrentNode.next != nil; | |
} | |
- (BOOL)isPrevious { | |
MTLinkedListNode *strongCurrentNode = _currentNode; | |
return strongCurrentNode && strongCurrentNode.prev; | |
} | |
- (id)objectAtIndex:(NSUInteger)index { | |
if (index >= _count) return nil; | |
MTLinkedListNode *node = _headNode; | |
for (NSUInteger i = 0; i < index; i++) { | |
node = node.next; | |
} | |
return node.data; | |
} | |
- (void)reverse { | |
MTLinkedListNode *current = _headNode; | |
MTLinkedListNode *temp = nil; | |
while (current) { | |
temp = current.prev; | |
current.prev = current.next; | |
current.next = temp; | |
current = current.prev; | |
} | |
if (temp) { | |
_tailNode = _headNode; | |
_headNode = temp.prev; | |
} | |
} | |
- (NSArray *)toArray { | |
NSMutableArray *array = [NSMutableArray arrayWithCapacity:_count]; | |
MTLinkedListNode *node = _headNode; | |
while (node) { | |
[array addObject:node.data]; | |
node = node.next; | |
} | |
return [array copy]; | |
} | |
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state | |
objects:(id __unsafe_unretained [])stackbuf | |
count:(NSUInteger)len { | |
if (state->state >= _count) { | |
return 0; | |
} | |
NSUInteger batchCount = 0; | |
MTLinkedListNode *node = (state->state == 0) ? _headNode : (__bridge MTLinkedListNode *)(void *)state->extra[0]; | |
while (node && batchCount < len) { | |
stackbuf[batchCount] = node.data; | |
node = node.next; | |
batchCount++; | |
} | |
state->state += batchCount; | |
state->itemsPtr = stackbuf; | |
state->mutationsPtr = &state->extra[1]; | |
state->extra[0] = (unsigned long)(__bridge void *)node; | |
return batchCount; | |
} | |
@end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MTLinkedListNode.h | |
// MADDataStructures | |
// | |
// Created by Michael on 11/23/24. | |
// Copyright © 2024 Everyday Apps LLC. All rights reserved. | |
// | |
#import <Foundation/Foundation.h> | |
NS_ASSUME_NONNULL_BEGIN | |
@interface MTLinkedListNode : NSObject | |
@property (nonatomic, strong) id data; | |
@property (nonatomic, strong, nullable) MTLinkedListNode *next; | |
@property (nonatomic, strong, nullable) MTLinkedListNode *prev; | |
- (instancetype)initWithData:(id)data; | |
@end | |
NS_ASSUME_NONNULL_END |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// MTLinkedListNode.m | |
// MADDataStructures | |
// | |
// Created by Michael on 11/23/24. | |
// Copyright © 2024 Everyday Apps LLC. All rights reserved. | |
// | |
#import "MTLinkedListNode.h" | |
@implementation MTLinkedListNode | |
- (instancetype)initWithData:(id)data { | |
if (self = [super init]) { | |
_data = data; | |
_next = nil; | |
_prev = nil; | |
} | |
return self; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment