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

本次要实现的队列要求:

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

2. 线程安全

简单说明一下:

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

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

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

CFList.h文件

 //
// CFList.h
// ListTest
//
// Created by MiaoCF on 2018/2/26.
// Copyright © 2018年 MiaoCF. All rights reserved.
// #import <Foundation/Foundation.h> typedef BOOL(^CFComparator)(id obj1, id obj2); @interface CFNode : NSObject @property (atomic, strong) id data;
@property (atomic, strong) CFNode *next;
@end @interface CFList : NSObject @property (atomic, strong, readonly) CFNode *head;
@property (atomic, strong, readonly) CFNode *tail;
@property (atomic, assign, readonly) NSInteger size; // 1 creat
- (instancetype)initList; // 2 appendNode
- (void)appendData:(id)data; // 3 popNode
- (id)popNode; // 4 deleteNode
- (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator;// func equal to find node
@end

CFList.m文件

注意:

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

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

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

 //
// CFList.m
// ListTest
//
// Created by MiaoCF on 2018/2/26.
// Copyright © 2018年 MiaoCF. All rights reserved.
// #import "CFList.h" @implementation CFNode
@end @interface CFList()
@property (atomic, strong) NSLock *mutex;
@end @implementation CFList - (instancetype)initList { self = [super init]; _mutex = [[NSLock alloc] init]; self.head = nil;
self.tail = nil; return self;
} // idea: 记录 head 和 tail 节点, head只管删除节点, tail只管添加节点 - (void)appendData:(id)data {
[_mutex lock]; CFNode *node = [[CFNode alloc] init];
node.data = data;
node.next = nil; if (_head == nil) {
_head = node;
} else {
_tail.next = node;
}
_tail = node;
_size ++; [_mutex unlock];
} - (id)popNode {
[_mutex lock]; id res = nil; if (_head != nil) {
res = _head.data; CFNode *temp = _head;
_head = temp.next;
if (_head == nil) {
_tail = nil;
} temp.next = nil;
_size --;
} [_mutex unlock];
return res;
} // 节点重复问题: 有多个节点数据相同 如何处理? - (BOOL)deletNode:(CFNode *)node with:(CFComparator)comparator{ [_mutex lock]; //空链表
if (_head == nil) {
[_mutex unlock];
return NO;
} CFNode *currentNode = _head;
CFNode *previousNode = currentNode; //从第二个节点开始判断
while (currentNode) { if (comparator(currentNode, node)) { //移除节点 previousNode.next = currentNode.next;
currentNode.next = nil; // 节点重复问题: 有多个节点数据相同 全部删除
if (previousNode.next == nil) { // 一直遍历到末尾,可以清除重复节点 [_mutex unlock];
return YES;
}
}
previousNode = currentNode;
currentNode = currentNode.next; } [_mutex unlock];
return NO;
}
113 @end

OC实现 单向链表的更多相关文章

  1. 复习下C 链表操作(单向链表)

    Object-C 作为C 的包装语言(运行时.消息机制).如果不熟悉C 的话实在玩得太肤浅. 随便深入oc 内部都会接触到C. runtime .GCD.Block.消息机制... 所有强大的功能无不 ...

  2. Reverse Linked List II 单向链表逆序(部分逆序)

    0 问题描述 原题点击这里. 将单向链表第m个位置到第n个位置倒序连接.例如, 原链表:1->2->3->4->5, m=2, n =4 新链表:1->4->3-& ...

  3. 【编程题目】输入一个单向链表,输出该链表中倒数第 k 个结点

    第 13 题(链表):题目:输入一个单向链表,输出该链表中倒数第 k 个结点.链表的倒数第 0 个结点为链表的尾指针.链表结点定义如下: struct ListNode {int m_nKey;Lis ...

  4. 输出单向链表中倒数第k个结点

    描述 输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针. 链表结点定义如下: struct ListNode { int       m_nKey; ListNode* ...

  5. Linus:利用二级指针删除单向链表

    Linus大神在slashdot上回答一些编程爱好者的提问,其中一个人问他什么样的代码是他所喜好的,大婶表述了自己一些观点之后,举了一个指针的例子,解释了什么才是core low-level codi ...

  6. 【转】Linus:利用二级指针删除单向链表

    原文作者:陈皓 原文链接:http://coolshell.cn/articles/8990.html 感谢网友full_of_bull投递此文(注:此文最初发表在这个这里,我对原文后半段修改了许多, ...

  7. C语言实现单向链表及其各种排序(含快排,选择,插入,冒泡)

    #include<stdio.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student / ...

  8. 数据结构——Java实现单向链表

    结点类: /** * @author zhengbinMac * 一个OnelinkNode类的对象只表示链表中的一个结点,通过成员变量next的自引用方式实现线性表中各数据元素的逻辑关系. */ p ...

  9. 输入一个单向链表,输出该链表中倒数第K个结点

    输入一个单向链表,输出该链表中倒数第K个结点,具体实现如下: #include <iostream> using namespace std; struct LinkNode { publ ...

随机推荐

  1. java IO流实现删除文件夹以及文件夹中的内容

    这篇主要是对IO文件流对文件常用处理中的删除文件夹,平时我们直接删除文件夹既可以删除里面的全部内容. 但是java在实现删除时,只能是文件才会被删除. 所以这里需要定义一个方法,来递归调用方法(递归调 ...

  2. php浮点数加减乘除bug

    项目测试阶段,少部分微信支付成功,但是在异步通知校对订单金额是否一致时,一直被认定订单金额不一致. 类似于: 浏览器输出: 分析: 因为计算机二进制无法准确表示部分浮点数(如2.03.0.58等等), ...

  3. 计算(calc.cpp)

    计算(calc.cpp) [问题描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*” ...

  4. .net CombinedGeometry的合并模式

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="h ...

  5. Java中的volatile关键字的功能

    Java中的volatile关键字的功能 volatile是java中的一个类型修饰符.它是被设计用来修饰被不同线程访问和修改的变量.如果不加入volatile,基本上会导致这样的结果:要么无法编写多 ...

  6. Day02——Python基本数据类型

    一.运算符 1.算数运算符 2.比较运算符 3.复制运算符 4.逻辑运算符 5.成员运算符 二.基本数据类型 1.数字 整数(int) 在32位机器上,整数的位数为32位,取值范围为-2**31-2* ...

  7. fork: retry: Resource temporarily unavailable

    用户A打开文件描述符太多,超过了该用户的限制 修改用户可以打开的文件描述符数量 1.首先,用另一个用户B登录,修改/etc/security/limit.conf * soft nofile 6553 ...

  8. linux下 signal信号机制的透彻分析与各种实例讲解

    转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/det ...

  9. Oracle 查看占用undo大的sql语句

    select s.sid,s.serial#,s.sql_id,v.usn,segment_name,r.status, v.rssize/1024/1024 mb     from dba_roll ...

  10. 远程计算机或设备将不接受连接,IE无法上网

    遇到一个奇葩问题,IE浏览器突然不能上网了,但是其他浏览器可以,QQ什么的也都正常,只有IE是出现:远程计算机或设备将不接受连接 这个问题,网上找了很多答案都没用,什么设置WINS,允许远程访问,取消 ...