1
/**/
/*========带头节点的线性链表类型=========*/
2
/**/
/*=======================================*/
3
4
5
/**/
/*===============包含头文件以及类型定义==============*/
6
#include
<
stdio.h
>
7
#include
<
malloc.h
>
8
#define
NULL 0
9
#define
NODE_NUM 10
10
11
12
typedef
struct
lnode
{
13
char data;
14
struct lnode *next;
15
}
*
link,
*
position;
16
17
18
typedef
struct
{
19
link head,tail;
20
int len;
21
}
linklist;
22
23
24
/**/
/*======================================================*/
25
/**/
/*=======一些在其他函数定义中会调用的函数===============*/
26
/**/
/*======================================================*/
27
28
int
compare(
char
a,
char
b)
{ /**//*---compare---比较两个元素的大小关系*/
29
return a-b;
30
}
31
32
33
int
visit(link p)
{
34
if(p->data>=65&&p->data<=97)/**//*---visit---判断结点的元素是否为大写元素*/
35
return 1;
36
else
37
return 0;
38
39
}
40
41
42
int
length(link s)
{ /**//*---length---求链的长度*/
43
int i=0;/**//*i不赋初值,编译错误“可能在i定义以前使用了它在length函数中”*/
44
link p=NULL;
45
p=s;
46
while(p->next!=NULL)
{
47
p=p->next;
48
i++;
49
}
50
return i;
51
}
52
53
54
void
print(linklist l)
{ /**//*---print---在屏幕上输出链表的所有元素*/
55
link p=NULL;
56
p=l.head;
57
if(!p->next)
{
58
printf("\nThe linklist is empty.\n\n");
59
return ;
60
}
61
printf("The list:");
62
while(p)
{
63
printf("%c-",p->data);
64
p=p->next;
65
}
66
}
67
68
69
70
/**/
/*======================================================*/
71
/**/
/*==========对带头结点的单链线性表进行操作的函数的定义==================*/
72
/**/
/*======================================================*/
73
74
position makenode(
char
e)
{ /**//*---分配由p指向的结点并赋值为e---*/
75
link p=NULL;
76
p=(link)malloc(sizeof(struct lnode));
77
/**//*---struct lnode 才能表示一个结构体类型并可用于分配空间的元素类型定义-*/
78
if(p)
{
79
p->data=e;
80
p->next=NULL;
81
}
82
else return;
83
return p;
84
}
85
86
87
void
freenode(link p)
{ /**//*---释放p所指向的结点-*/
88
free(p);
89
}
90
91
92
93
int
initlist(linklist
*
l)
{ /**//*---构造一个由l指向的空的线性表-*/
94
l->head=makenode('L');
95
l->head->next=NULL;/**//*不是l->head=NULL*/
96
l->tail=l->head;
97
l->len=0;
98
return 1;
99
}
100
101
102
position priorpos(linklist l,link p)
{ /**//*---返回p所指结点的直接前驱的位置-*/
103
link q;
104
q=l.head;
105
if(q->next==p) return 0;
106
while(q->next!=p) q=q->next;
107
return q;
108
}
109
110
111
int
insfirst(linklist
*
l,link s)
{ /**//*---将s指向的结点插入线性链表的第一个结点之前-*/
112
s->next=l->head->next;
113
if(!l->head->next) l->tail=s;/**//*当向一个空的线性表执行该操作时*/
114
l->head->next=s;
115
l->len++;
116
117
}
118
119
120
int
append(linklist
*
l,link s)
{ /**//*---将指针s所的一串结点链接在线性表L的最后一个结点-*/
121
link q;
122
q=l->head;
123
if(!l->tail)
{/**//*考虑到链表为空的情况*/
124
l->head->next=s;
125
while(q->next) q=q->next;/**//*尾结点的处理*/
126
l->tail=q;
127
}
128
l->tail->next=q=s;
129
while(q->next) q=q->next;/**//*不能忘了对尾结点的处理*/
130
l->tail=q;
131
l->len+=length(s);
132
133
}
134
135
position delfirst(linklist
*
l,link q)
{ /**//*---删除表中第一个结点并以q返回-*/
136
if(!l->head->next)
{
137
printf("\nThe linklist is empty,can not delete..\n");
138
return 0;
139
}
140
q=l->head->next;
141
l->head->next=l->head->next->next;
142
return q;
143
}
144
145
146
position remonode(linklist
*
l,link q)
{ /**//*---删除线性表l中的尾结点-*/
147
if(!l->tail)
{
148
printf("\nthe linklist is empty,can not remonde..\n");
149
return 0;
150
}
151
q=l->tail; /**//*用书上函数名remove时,编译错误“调用参数个数出错”*/
152
l->tail=priorpos(*l,q);
153
l->tail->next=NULL;
154
return q;
155
}
156
157
158
int
insbefore(linklist
*
l,link p,link s)
{ /**//*---将s所指向结点插入在p所指结点之前-*/
159
link q;
160
q=priorpos(*l,p);
161
s->next=p;
162
q->next=s;
163
}
164
165
166
int
insafter(link p,link s)
{ /**//*---将s所指向结点插入在p所指结点之后-*/
167
s->next=p->next;
168
p->next=s;
169
}
170
171
172
int
setcurelem(link p,
char
e)
{ /**//*---用e更新p所指向的当前结点-*/
173
p->data=e;
174
}
175
176
177
char
getcurelem(link p)
{ /**//*---返回p所指结点中元素的值-*/
178
return p->data;
179
}
180
181
182
int
listempty(linklist l)
{ /**//*---若线性表为空表则返回1,否则返回0-*/
183
if(l.head==l.tail) return 1;
184
return 0;
185
}
186
187
188
int
listlength(linklist l)
{ /**//*---返回线性表中元素个数-*/
189
return l.len;
190
}
191
192
193
position gethead(linklist l)
{ /**//*---返回线性表l中头结点的位置-*/
194
return l.head;
195
}
196
197
198
position getlast(linklist l)
{ /**//*-----返回线性表l中最后一个结点的位置-------*/
199
return l.tail;
200
}
201
202
203
position nextpos(link p)
{ /**//*-----返回p所指结点的直接后继的位置-------*/
204
link q;
205
q=p->next;
206
return q;
207
}
208
209
210
position locatepos(linklist l,
int
i,link p)
{ /**//*-----用p返回线性表l中第i个结点的位置,并返回ok-------*/
211
p=l.head;
212
if(i<=0||i>listlength(l)) return 0;
213
while(i)
{
214
p=p->next;
215
i--;
216
}
217
return p;
218
}
219
220
221
int
locatelem(linklist l,
char
e)
{ /**//*----返回表中第一个与e满足一定函数关系的结点次序位置--------*/
222
int i=0;
223
link p;
224
p=l.head->next;
225
while(compare(p->data,e)&&p)
{
226
p=p->next;
227
++i;
228
}
229
if(!p)
{/**//*考虑到查找不到指定元素的情况*/
230
printf("\nthere's no '%c' in this linklist.",e);
231
return 0;
232
}
233
return i;
234
}
235
236
237
int
listraverse(linklist l)
{ /**//*----用一个函数遍历表中所有结点-------*/
238
link p;
239
p=l.head;
240
while(!visit(p)) p=p->next;
241
if(p!=l.tail) return 0;
242
243
}
244
245
246
247
248
249
int
clearlist(linklist
*
l)
{ /**//*----?------将线性表l置为空表,并释放原链表的结点?*/
250
link p;
251
p=(*l).tail;
252
while(p!=(*l).head)
{
253
p=priorpos(*l,p);
254
freenode(p->next);
255
}
256
freenode((*l).head);
257
258
}
259
260
int
destroylist(linklist
*
l)
{ /**//*----------销毁由l指向的线性表---------*/
261
link p;
262
p=(*l).tail;
263
while(p!=(*l).head)
{
264
p=priorpos(*l,p);
265
freenode(p->next);
266
}
267
freenode((*l).head);
268
}
269
270
271
272
273
274
/**/
/*=======================================================*/
275
/**/
/*==================主函数部分===================*/
276
/**/
/*=======================================================*/
277
main()
{
278
int i;
279
char temp='a';
280
linklist *l,*la=NULL,*lb,*lc=NULL;
281
link s,s_nodes,q,p,n;
282
283
284
initlist(l);
285
/**//*调用初始化函数,构造一个由l指向的线性链表*/
286
printf("l->head->data:%c ",l->head->data);
287
print(*l);
288
289
for(i=1;i<=5;i++)
{
290
s=makenode(temp++);/**//*每次插入结点都要重新分配空间,否则无限循环*/
291
insfirst(l,s);
292
/**//*将s指向的结点插入在以(*l).head为头结点的链表的第一个元素之前*/
293
}
294
printf("insfirst(l,s)*5, ");
295
print(*l);
296
297
s_nodes=s=makenode(temp++);/**//*_1_*/
298
printf("\ns_nodes:");
299
for(i=1;i<=NODE_NUM;i++)
{
300
s->next=makenode(temp++);/**//*_2_*/
301
printf("%c ",s->data);
302
s=s->next;
303
}/**//*构造了一串由s_nodes指向的链,并为其中的数据项赋值*/
304
305
append(l,s_nodes);
306
/**//*将由s_nodes指向的一串结点附加到l指向的链表的后面*/
307
printf("\nappend(l,s_nodes), ");
308
print(*l);
309
310
q=delfirst(l,q);/**//*---*/
311
/**//*删除以(*l).head为头结点的链表中的第一个结点并以q返回*/
312
printf("\ndelfirst(l,q), ");
313
print(*l);
314
printf("\nthe deleted element:%c",q->data);
315
316
q=remonode(l,q);
317
/**//*删除l指向的线性表的尾结点并以q返回*/
318
printf("\nremonode(l,q), ");
319
print(*l);
320
printf("\nthe removed element:%c\n",q->data);
321
322
323
p=l->head;
324
for(i=1;i<=5;++i)
{
325
p=p->next;
326
}/**//*移动指针p使其指向链表中的第六个结点*/
327
printf("\np->data:%c, ",p->data);
328
329
s=makenode(temp++);
330
printf("s->data:%c",s->data);
331
insbefore(l,p,s);
332
/**//*将s指向的结点插入到p指向的结点之前*/
333
printf("\ninsbefore(l,p,s), ");
334
print(*l);
335
336
337
printf("\np->data:%c, ",p->data);
338
s=makenode(temp++);
339
printf("\ns->data:%c",s->data);
340
insafter(p,s);
341
/**//*将s指向的结点插入到p指向的结点之后*/
342
printf("\ninsafter(p,s),");
343
print(*l);
344
345
setcurelem(p,temp++);
346
/**//*将p指向的结点的数据项赋值为temp*/
347
printf("\np->data:%c, ",p->data);
348
printf("setcurelem(p,temp++),");
349
print(*l);
350
351
n=s;
352
printf("\ncurrent element:%c\n",getcurelem(n));
353
/**//*在printf函数中调用getcurelem函数,返回n指向的结点的值*/
354
printf("the listlinks'length:%d\n",listlength(*l));
355
/**//*在pringf函数中调用listlength函数,返回当前链表的元素个数*/
356
357
printf("priorpos(list,p):%c\n",priorpos(*l,p)->data);
358
/**//*返回p所指结点的直接前驱的位置*/
359
360
printf("\nnextpos(p):%c\n",nextpos(p)->data);
361
/**//*返回p所指结点的直接后继的位置*/
362
363
print(*l);
364
printf("\nthe element 'e' located at position %d\n",locatelem(*l,'e'));
365
/**//*返回l所指向的链表中元素值为e的结点的位置*/
366
printf("the element 'i' located at position %d\n",locatelem(*l,'i'));
367
/**//*返回l所指向的链表中元素值为e的结点的位置*/
368
369
p=locatepos(*l,6,p);
370
printf("the 6th element:%c",p->data);
371
372
if(!listraverse(*l))
373
printf("\nthere are all Lowercase letters\n");
374
/**//*判断l指向的链表中是否全都不是大写字母*/
375
376
377
/**//*=========表间操作=========*/
378
379
380
381
382
383
getch();
384
}
385
386
387


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

284

285


286

287

288

289



290


291

292


293

294

295

296

297


298

299



300


301

302

303


304

305

306


307

308

309

310


311


312

313

314

315

316

317


318

319

320

321

322

323

324



325

326


327

328

329

330

331

332


333

334

335

336

337

338

339

340

341


342

343

344

345

346


347

348

349

350

351

352

353


354

355


356

357

358


359

360

361


362

363

364

365


366

367


368

369

370

371

372

373

374


375

376

377


378

379

380

381

382

383

384

385

386

387
