浅谈iOS 数据结构之链表

2025-05-29 0 89

链表(linked list)是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,表现形式如下图所示:

链表

浅谈iOS 数据结构之链表

链表

浅谈iOS 数据结构之链表

数组和链表区别:

  • 数组:数组元素在内存上连续存放,可以通过下标查找元素;插入、删除需要移动大量元素,比较适用于元素很少变化的情况
  • 链表链表中的元素在内存中不是顺序存储的,查找慢,插入、删除只需要对元素指针重新赋值,效率高

objective-c 里没有现成的链表结构,下面我实现了非线程安全的单链表和双链表,以下都是具体的实现细节,完整代码可以在这儿下载

链表

链表提供了插入、删除、查询、反转等操作,具体实现如下:

bbsinglelinkedlist.h

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38
#import <foundation/foundation.h>

@interface bbsinglelinkednode : nsobject <nscopying>

@property (nonatomic, strong) nsstring *key;

@property (nonatomic, strong) nsstring *value;

@property (nonatomic, strong) bbsinglelinkednode *next;

- (instancetype)initwithkey:(nsstring *)key

value:(nsstring *)value;

+ (instancetype)nodewithkey:(nsstring *)key

value:(nsstring *)value;

@end

@interface bbsinglelinkedlist : nsobject

- (void)insertnode:(bbsinglelinkednode *)node;

- (void)insertnodeathead:(bbsinglelinkednode *)node;

- (void)insertnode:(bbsinglelinkednode *)newnode beforenodeforkey:(nsstring *)key;

- (void)insertnode:(bbsinglelinkednode *)newnode afternodeforkey:(nsstring *)key;

- (void)bringnodetohead:(bbsinglelinkednode *)node;

- (void)removenode:(bbsinglelinkednode *)node;

- (bbsinglelinkednode *)nodeforkey:(nsstring *)key;

- (bbsinglelinkednode *)headnode;

- (bbsinglelinkednode *)lastnode;

- (nsinteger)length;

- (bool)isempty;

- (void)reverse;

- (void)readallnode;

@end

bbsinglelinkedlist.m

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271
#import "bbsinglelinkedlist.h"

@implementation bbsinglelinkednode

- (instancetype)initwithkey:(nsstring *)key

value:(nsstring *)value

{

if (self = [super init]) {

_key = key;

_value = value;

}

return self;

}

+ (instancetype)nodewithkey:(nsstring *)key

value:(nsstring *)value

{

return [[[self class] alloc] initwithkey:key value:value];

}

#pragma mark - nscopying

- (id)copywithzone:(nullable nszone *)zone

{

bbsinglelinkednode *newnode = [[bbsinglelinkednode allocwithzone:zone] init];

newnode.key = self.key;

newnode.value = self.value;

newnode.next = self.next;

return newnode;

}

@end

@interface bbsinglelinkedlist ()

@property (nonatomic, strong) bbsinglelinkednode *headnode;

@property (nonatomic, strong) nsmutabledictionary *innermap;

@end

@implementation bbsinglelinkedlist

- (instancetype)init

{

self = [super init];

if (self) {

_innermap = [nsmutabledictionary new];

}

return self;

}

#pragma mark - public

- (void)insertnodeathead:(bbsinglelinkednode *)node

{

if (!node || node.key.length == 0) {

return;

}

if ([self isnodeexists:node]) {

return;

}

_innermap[node.key] = node;

if (_headnode) {

node.next = _headnode;

_headnode = node;

} else {

_headnode = node;

}

}

- (void)insertnode:(bbsinglelinkednode *)node

{

if (!node || node.key.length == 0) {

return;

}

if ([self isnodeexists:node]) {

return;

}

_innermap[node.key] = node;

if (!_headnode) {

_headnode = node;

return;

}

bbsinglelinkednode *lastnode = [self lastnode];

lastnode.next = node;

}

- (void)insertnode:(bbsinglelinkednode *)newnode beforenodeforkey:(nsstring *)key

{

if (key.length == 0 || !newnode || newnode.key.length == 0) {

return;

}

if ([self isnodeexists:newnode]) {

return;

}

if (!_headnode) {

_headnode = newnode;

return;

}

bbsinglelinkednode *node = _innermap[key];

if (node) {

_innermap[newnode.key] = newnode;

bbsinglelinkednode *aheadnode = [self nodebeforenode:node];

if (aheadnode) {

aheadnode.next = newnode;

newnode.next = node;

} else {

_headnode = newnode;

newnode.next = node;

}

} else {

[self insertnode:newnode]; //insert to tail

}

}

- (void)insertnode:(bbsinglelinkednode *)newnode afternodeforkey:(nsstring *)key

{

if (key.length == 0 || !newnode || newnode.key.length == 0) {

return;

}

if ([self isnodeexists:newnode]) {

return;

}

if (!_headnode) {

_headnode = newnode;

return;

}

bbsinglelinkednode *node = _innermap[key];

if (node) {

_innermap[newnode.key] = newnode;

newnode.next = node.next;

node.next = newnode;

} else {

[self insertnode:newnode]; //insert to tail

}

}

- (void)removenode:(bbsinglelinkednode *)node

{

if (!node || node.key.length == 0) {

return;

}

[_innermap removeobjectforkey:node.key];

if (node.next) {

node.key = node.next.key;

node.value = node.next.value;

node.next = node.next.next;

} else {

bbsinglelinkednode *aheadnode = [self nodebeforenode:node];

aheadnode.next = nil;

}

}

- (void)bringnodetohead:(bbsinglelinkednode *)node

{

if (!node || !_headnode) {

return;

}

if ([node isequal:_headnode]) {

return;

}

bbsinglelinkednode *aheadnode = [self nodebeforenode:node];

aheadnode.next = node.next;

node.next = _headnode;

_headnode = node;

}

- (bbsinglelinkednode *)nodeforkey:(nsstring *)key

{

if (key.length == 0) {

return nil;

}

bbsinglelinkednode *node = _innermap[key];

return node;

}

- (bbsinglelinkednode *)headnode

{

return _headnode;

}

- (bbsinglelinkednode *)lastnode

{

bbsinglelinkednode *last = _headnode;

while (last.next) {

last = last.next;

}

return last;

}

- (void)reverse

{

bbsinglelinkednode *prev = nil;

bbsinglelinkednode *current = _headnode;

bbsinglelinkednode *next = nil;

while (current) {

next = current.next;

current.next = prev;

prev = current;

current = next;

}

_headnode = prev;

}

- (void)readallnode

{

bbsinglelinkednode *tmpnode = _headnode;

while (tmpnode) {

nslog(@"node key -- %@, node value -- %@", tmpnode.key, tmpnode.value);

tmpnode = tmpnode.next;

}

}

- (nsinteger)length

{

nsinteger _len = 0;

for (bbsinglelinkednode *node = _headnode; node; node = node.next) {

_len ++;

}

return _len;

}

- (bool)isempty

{

return _headnode == nil;

}

#pragma mark - private

- (bbsinglelinkednode *)nodebeforenode:(bbsinglelinkednode *)node

{

bbsinglelinkednode *targetnode = nil;

bbsinglelinkednode *tmpnode = _headnode;

while (tmpnode) {

if ([tmpnode.next isequal:node]) {

targetnode = tmpnode;

break;

} else {

tmpnode = tmpnode.next;

}

}

return targetnode;

}

- (bool)isnodeexists:(bbsinglelinkednode *)node

{

bbsinglelinkednode *tmpnode = _headnode;

while (tmpnode) {

if ([tmpnode isequal:node]) {

return yes;

}

tmpnode = tmpnode.next;

}

return false;

}

@end

链表

链表提供了插入、删除、查询操作,具体实现如下:

bblinkedmap.h

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37
#import <foundation/foundation.h>

@interface bblinkednode : nsobject <nscopying>

@property (nonatomic, strong) nsstring *key;

@property (nonatomic, strong) nsstring *value;

@property (nonatomic, strong) bblinkednode *prev;

@property (nonatomic, strong) bblinkednode *next;

- (instancetype)initwithkey:(nsstring *)key

value:(nsstring *)value;

+ (instancetype)nodewithkey:(nsstring *)key

value:(nsstring *)value;

@end

@interface bblinkedmap : nsobject

- (void)insertnodeathead:(bblinkednode *)node;

- (void)insertnode:(bblinkednode *)node;

- (void)insertnode:(bblinkednode *)newnode beforenodeforkey:(nsstring *)key;

- (void)insertnode:(bblinkednode *)newnode afternodeforkey:(nsstring *)key;

- (void)bringnodetohead:(bblinkednode *)node;

- (void)readallnode;

- (void)removenodeforkey:(nsstring *)key;

- (void)removetailnode;

- (nsinteger)length;

- (bool)isempty;

- (bblinkednode *)nodeforkey:(nsstring *)key;

- (bblinkednode *)headnode;

- (bblinkednode *)tailnode;

@end

bblinkedmap.m

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283
#import "bblinkedmap.h"

@implementation bblinkednode

- (instancetype)initwithkey:(nsstring *)key

value:(nsstring *)value

{

if (self = [super init]) {

_key = key;

_value = value;

}

return self;

}

+ (instancetype)nodewithkey:(nsstring *)key

value:(nsstring *)value

{

return [[[self class] alloc] initwithkey:key value:value];

}

#pragma mark - nscopying

- (id)copywithzone:(nullable nszone *)zone

{

bblinkednode *newnode = [[bblinkednode allocwithzone:zone] init];

newnode.key = self.key;

newnode.value = self.value;

newnode.prev = self.prev;

newnode.next = self.next;

return newnode;

}

@end

@interface bblinkedmap ()

@property (nonatomic, strong) bblinkednode *headnode;

@property (nonatomic, strong) bblinkednode *tailnode;

@property (nonatomic, strong) nsmutabledictionary *innermap;

@end

@implementation bblinkedmap

- (instancetype)init

{

self = [super init];

if (self) {

_innermap = [nsmutabledictionary new];

}

return self;

}

#pragma mark - public

- (void)insertnodeathead:(bblinkednode *)node

{

if (!node || node.key.length == 0) {

return;

}

if ([self isnodeexists:node]) {

return;

}

_innermap[node.key] = node;

if (_headnode) {

node.next = _headnode;

_headnode.prev = node;

_headnode = node;

} else {

_headnode = _tailnode = node;

}

}

- (void)insertnode:(bblinkednode *)node

{

if (!node || node.key.length == 0) {

return;

}

if ([self isnodeexists:node]) {

return;

}

if (!_headnode && !_tailnode) {

_headnode = _tailnode = node;

return;

}

_innermap[node.key] = node;

_tailnode.next = node;

node.prev = _tailnode;

_tailnode = node;

}

- (void)insertnode:(bblinkednode *)newnode beforenodeforkey:(nsstring *)key

{

if (key.length == 0 || !newnode || newnode.key.length == 0) {

return;

}

if ([self isnodeexists:newnode]) {

return;

}

if (!_headnode && !_tailnode) {

_headnode = _tailnode = newnode;

return;

}

bblinkednode *node = _innermap[key];

if (node) {

_innermap[newnode.key] = newnode;

if (node.prev) {

node.prev.next = newnode;

newnode.prev = node.prev;

} else {

_headnode = newnode;

}

node.prev = newnode;

newnode.next = node;

} else {

[self insertnode:newnode]; //insert to tail

}

}

- (void)insertnode:(bblinkednode *)newnode afternodeforkey:(nsstring *)key

{

if (key.length == 0 || !newnode || newnode.key.length == 0) {

return;

}

if ([self isnodeexists:newnode]) {

return;

}

if (!_headnode && !_tailnode) {

_headnode = _tailnode = newnode;

return;

}

bblinkednode *node = _innermap[key];

if (node) {

_innermap[newnode.key] = newnode;

if (node.next) {

newnode.next = node.next;

node.next.prev = newnode;

} else {

_tailnode = newnode;

}

newnode.prev = node;

node.next = newnode;

} else {

[self insertnode:newnode]; //insert to tail

}

}

- (void)bringnodetohead:(bblinkednode *)node

{

if (!node) {

return;

}

if (!_headnode && !_tailnode) {

_headnode = _tailnode = node;

return;

}

if ([_headnode isequal:node]) {

return;

}

if ([_tailnode isequal:node]) {

_tailnode = node.prev;

_tailnode.next = nil;

} else {

node.prev.next = node.next;

node.next.prev = node.prev;

}

_headnode.prev = node;

node.next = _headnode;

node.prev = nil;

_headnode = node;

}

- (void)removenodeforkey:(nsstring *)key

{

if (key.length == 0) {

return;

}

bblinkednode *node = _innermap[key];

if (!node) {

return;

}

[_innermap removeobjectforkey:key];

if ([_headnode isequal:node]) {

_headnode = node.next;

} else if ([_tailnode isequal:node]) {

_tailnode = node.prev;

}

node.prev.next = node.next;

node.next.prev = node.prev;

}

- (void)removetailnode

{

if (!_tailnode || _tailnode.key.length == 0) {

return;

}

[_innermap removeobjectforkey:_tailnode.key];

if (_headnode == _tailnode) {

_headnode = _tailnode = nil;

return;

}

_tailnode = _tailnode.prev;

_tailnode.next = nil;

}

- (bblinkednode *)nodeforkey:(nsstring *)key

{

if (key.length == 0) {

return nil;

}

bblinkednode *node = _innermap[key];

return node;

}

- (bblinkednode *)headnode

{

return _headnode;

}

- (bblinkednode *)tailnode

{

return _tailnode;

}

- (void)readallnode

{

bblinkednode *node = _headnode;

while (node) {

nslog(@"node key -- %@, node value -- %@", node.key, node.value);

node = node.next;

}

}

- (nsinteger)length

{

nsinteger _len = 0;

for (bblinkednode *node = _headnode; node; node = node.next) {

_len ++;

}

return _len;

}

- (bool)isempty

{

return _headnode == nil;

}

#pragma mark - private

- (bool)isnodeexists:(bblinkednode *)node

{

bblinkednode *tmpnode = _headnode;

while (tmpnode) {

if ([tmpnode isequal:node]) {

return yes;

}

tmpnode = tmpnode.next;

}

return false;

}

@end

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 浅谈iOS 数据结构之链表 https://www.kuaiidc.com/89404.html

相关文章

发表评论
暂无评论