The following is the actual Objective C class that implements a doubly-linked list (a variation of ​​LinkedList​​). It can do the following:

 


  • Addition of new elements to the front of the list
  • Forward traversal using internal iterator
  • Backward traversal
  • Removal of the item the iterator points at

Here's the interface .h file:

 

//

//  LinkedList.h

//

 

// Structure representing a 

// doubly-linked list node.

typedef struct ListNode ListNode;

struct ListNode {

int value;

ListNode *next;

ListNode *prev;

};

 

 

@interface LinkedList : NSObject {

@private 

ListNode *head;

ListNode *iterator;

//bool reachedHead;

//bool reachedTail;

}

 

- (id)initWithHead: (int)value;

- (void)addToFront: (int)value;

- (int)getFirst;

- (int)getCurrent;

- (int)getNext;

- (int)getPrevious;

 

- (bool)atHead;

- (bool)atTail;

 

- (int)removeCurrent;

 

@end

Now for the implementation .m file:

 

 

//

//  LinkedList.m

//

 

#import "LinkedList.h"

 

 

@implementation LinkedList

 

 

/* Instantiates new linked list with a 

 * given first element. 

 */

- (id)initWithHead: (int)value 

{

ListNode *n;

    self = [super init];

    if (self) {

// creating head node with given value

n = (ListNode *)malloc(sizeof(ListNode));

n->value = value;

n->next = NULL;

n->prev = NULL;

head = n;

// initializing iterator to default

[self getFirst];

    }

    return self;

}

 

 

/* Adds a new element to the

 * front of the list */

- (void)addToFront: (int)value

{

ListNode *n = (ListNode *)malloc(sizeof(ListNode));

n->value = value;

n->next = head;

n->prev = NULL;

// new element becomes the head node

head->prev = n;

head = n;

}

 

 

/* Sets internal iterator to

 * the head node and returns its

 * value */

- (int)getFirst {

iterator = head;

//reachedHead = TRUE;

//reachedTail = FALSE;

return (head->value);

}

 

/* Returns the value of the iterator node

 */

- (int)getCurrent {

return (iterator->value);

}

 

 

/* Iterates to the next node in order and

 * returns its value */

/*

 - (int)getNext

 {

 // if we are finished iterating,

 // set the end-of-list flag

 if (iterator->next == NULL) {

 reachedTail = TRUE;

 } else {

 // if we're leaving the head

 // node, set the flag

 if (iterator->prev == NULL) {

 reachedHead = FALSE;

 }

 iterator = iterator->next;

 }

 return (iterator->value);

 }

 */

- (int)getNext

{

if (iterator->next != NULL) {

iterator = iterator->next;

}

return (iterator->value);

}

 

 

/* Iterates to the previous node in 

 * order and returns its value */

/*

 - (int)getPrevious

 {

 if (iterator->prev == NULL) {

 reachedHead = TRUE;

 } else {

 if (iterator->next == NULL) {

 reachedTail = FALSE;

 }

 iterator = iterator->prev;

 }

 return (iterator->value);

 }

 */

- (int)getPrevious

{

if (iterator->prev != NULL) {

iterator = iterator->prev;

}

return (iterator->value);

}

 

 

/* Indicates that iterator

 * is at the first (head) node */

- (bool)atHead 

{

//return reachedHead;

return (iterator->prev == NULL);

}

 

 

/* Indicates that iterator

 * is at the last (tail) node */

- (bool)atTail 

{

//return reachedTail;

return (iterator->next == NULL);

}

 

 

/* Removes the iterator node from

 * the list and advances iterator to the

 * next element. If there's no next element,

 * then it backs iterator up to the previous

 * element. Returns the old iterator value */

- (int)removeCurrent 

{

int i = iterator->value;

ListNode *l;

// if we have only 1 item in the list...

if ((iterator->next == NULL) && (iterator->prev == NULL)) {

//... then we can safely delete it and set head to null

free(iterator);

iterator = NULL;

head = NULL;

} else {

// sawing the gap between nodes

l = iterator;

if (iterator->next != NULL) {

iterator->next->prev = iterator->prev;

}

if (iterator->prev != NULL) {

iterator->prev->next = iterator->next;

}

// finally setting new iterator

iterator = (iterator->next != NULL) ? iterator->next : iterator->prev;

free(l);

}

// returning old value

return i;

}

 

@end

 

 

So, essentially this is it. I assume the basic knowledge of how linked list operates. You can just plug in this class and use it in your programs, although I think several things need to be added for comfortable operation, like element search e.t.c. You can test this class with a test sniplet like the following:

 

 

#import <Foundation/Foundation.h>

#import "LinkedList.h"

 

int main (int argc, const char * argv[]) {

    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 

    // insert code here...

LinkedList *test = [[LinkedList alloc] initWithHead: 0];

 

// testing addition

int i;

for (i = 1; i < 11; i++) {

[test addToFront: i];

}

NSLog(@"-- Added 10 values");

 

// testing forward traversal

NSLog(@"-- Setting iterator to first node: %d", [test getFirst]);

NSLog(@"-- Going forward until we hit the last element...");

do {

NSLog(@"---- Next element: %d", [test getNext]);

} while ([test atTail] == FALSE);

NSLog(@"-- We've hit the last element");

 

// testing back traversal

NSLog(@"-- Going back until we hit the first element...");

do {

NSLog(@"---- Previous element: %d", [test getPrevious]);

} while ([test atHead] == FALSE);

NSLog(@"-- We've hit the first element");

 

// testing removal

NSLog(@"-- Going forward 5 times");

for (i = 0; i < 5; i++)

NSLog(@"-- Next element: %d", [test getNext]);

NSLog(@"-- Current element with value %d", [test getCurrent]);

NSLog(@"-- Removing element with value %d", [test removeCurrent]);

NSLog(@"-- Continue forward traversal");

do {

NSLog(@"---- Next element: %d", [test getNext]);

} while ([test atTail] == FALSE);

NSLog(@"-- We've hit the last element");

 

NSLog(@"-- Returning to front, going forward until we reach end");

NSLog(@"-- First element: %d", [test getFirst]);

do {

NSLog(@"---- Next element: %d", [test getNext]);

} while ([test atTail] == FALSE);

NSLog(@"-- We've hit the last element");

 

    [pool release];

    return 0;

}