OC实现 单向链表

需要实现一个消息队列,队列具有 FIFO 特点,即先入先出,在这里采用单向链表实现队列逻辑。

本次要实现的队列要求:

1. 节点可以存放任意类型数据

2. 线程安全

 

简单说明一下:

1. 创建CFNode类,用作节点,其data属性和next属性都是 atomic,即只能单线程访问属性。

2. 创建CFList类,用以push节点和pop节点

3. 删除操作为不必要操作,在这里实现了纯属个人技痒,同理可实现节点更新、插入等操作,在这里不做过多介绍。

CFList.h文件

 1 //
 2 //  CFList.h
 3 //  ListTest
 4 //
 5 //  Created by MiaoCF on 2018/2/26.
 6 //  Copyright © 2018年 MiaoCF. All rights reserved.
 7 //
 8 
 9 #import <Foundation/Foundation.h>
10 
11 typedef BOOL(^CFComparator)(id obj1, id obj2);
12 
13 @interface CFNode : NSObject
14 
15 @property (atomic, strong) id data;
16 @property (atomic, strong) CFNode *next;
17 @end
18 
19 @interface CFList : NSObject
20 
21 @property (atomic, strong, readonly) CFNode *head;
22 @property (atomic, strong, readonly) CFNode *tail;
23 @property (atomic, assign, readonly) NSInteger size;
24 
25 // 1 creat
26 - (instancetype)initList;
27 
28 // 2 appendNode
29 - (void)appendData:(id)data;
30 
31 // 3 popNode
32 - (id)popNode;
33 
34 // 4 deleteNode
35 - (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator;// func equal to find node
36 @end

 

 

CFList.m文件

注意:

1. 使用了线程阻塞的互斥锁

2. 删除节点时,用户自己实现 CFComparator 进行比较。

3. 节点重复问题: 有多个节点数据相同 全部删除

  1 //
  2 //  CFList.m
  3 //  ListTest
  4 //
  5 //  Created by MiaoCF on 2018/2/26.
  6 //  Copyright © 2018年 MiaoCF. All rights reserved.
  7 //
  8 
  9 #import "CFList.h"
 10 
 11 @implementation CFNode
 12 @end
 13 
 14 @interface CFList()
 15 @property (atomic, strong) NSLock *mutex;
 16 @end
 17 
 18 @implementation CFList
 19 
 20 - (instancetype)initList {
 21     
 22     self = [super init];
 23     
 24     _mutex = [[NSLock alloc] init];
 25     
 26     self.head = nil;
 27     self.tail = nil;
 28     
 29     return self;
 30 }
 31 
 32 
 33 // idea: 记录 head 和 tail 节点, head只管删除节点, tail只管添加节点
 34 
 35 - (void)appendData:(id)data {
 36     [_mutex lock];
 37     
 38     CFNode *node = [[CFNode alloc] init];
 39     node.data = data;
 40     node.next = nil;
 41     
 42     if (_head == nil) {
 43         _head = node;
 44     } else {
 45         _tail.next = node;
 46     }
 47     _tail = node;
 48     _size ++;
 49     
 50     [_mutex unlock];
 51 }
 52 
 53 - (id)popNode {
 54     [_mutex lock];
 55     
 56     id res = nil;
 57     
 58     if (_head != nil) {
 59         res = _head.data;
 60         
 61         CFNode *temp = _head;
 62         _head = temp.next;
 63         if (_head == nil) {
 64             _tail = nil;
 65         }
 66         
 67         temp.next = nil;
 68         _size --;
 69     }
 70     
 71     [_mutex unlock];
 72     return res;
 73 }
 74 
 75 // 节点重复问题: 有多个节点数据相同 如何处理?
 76 
 77 - (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator{
 78     
 79     [_mutex lock];
 80     
 81     //空链表
 82     if (_head == nil) {
 83         [_mutex unlock];
 84         return NO;
 85     }
 86     
 87     CFNode *currentNode = _head;
 88     CFNode *previousNode = currentNode;
 89     
 90     //从第二个节点开始判断
 91     while (currentNode) {
 92         
 93         if (comparator(currentNode, node)) { //移除节点
 94             
 95             previousNode.next = currentNode.next;
 96             currentNode.next = nil;
 97             
 98             // 节点重复问题: 有多个节点数据相同 全部删除
 99             if (previousNode.next == nil) { // 一直遍历到末尾,可以清除重复节点
100                 
101                 [_mutex unlock];
102                 return YES;
103             }
104         }
105         previousNode = currentNode;
106         currentNode = currentNode.next;
107         
108     }
109     
110     [_mutex unlock];
111     return NO;
112 }
113 @end

 

posted @ 2018-02-27 14:26  CodeVector  阅读(416)  评论(0编辑  收藏