带头节点的线性链表类型[原创]

  1 ExpandedBlockStart.gif ContractedBlock.gif /**/ /*========带头节点的线性链表类型=========*/
  2 ExpandedBlockStart.gifContractedBlock.gif /**/ /*=======================================*/
  3
  4
  5 ExpandedBlockStart.gifContractedBlock.gif /**/ /*===============包含头文件以及类型定义==============*/
  6 #include  < stdio.h >
  7 #include  < malloc.h >
  8 #define  NULL 0
  9 #define  NODE_NUM 10
 10
 11
 12 ExpandedBlockStart.gifContractedBlock.giftypedef  struct  lnode {
 13    char data;
 14    struct lnode *next;
 15}
* link, * position;
 16
 17
 18 ExpandedBlockStart.gifContractedBlock.giftypedef  struct {
 19    link head,tail;
 20    int len;
 21}
linklist;
 22
 23
 24 ExpandedBlockStart.gifContractedBlock.gif /**/ /*======================================================*/
 25 ExpandedBlockStart.gifContractedBlock.gif /**/ /*=======一些在其他函数定义中会调用的函数===============*/
 26 ExpandedBlockStart.gifContractedBlock.gif /**/ /*======================================================*/
 27
 28 ExpandedBlockStart.gifContractedBlock.gif int  compare( char  a, char  b) {  /**//*---compare---比较两个元素的大小关系*/
 29    return a-b;
 30}

 31
 32
 33 ExpandedBlockStart.gifContractedBlock.gif int  visit(link p) {
 34ExpandedSubBlockStart.gifContractedSubBlock.gif    if(p->data>=65&&p->data<=97)/**//*---visit---判断结点的元素是否为大写元素*/
 35        return 1;
 36    else
 37        return 0;
 38
 39}

 40
 41
 42 ExpandedBlockStart.gifContractedBlock.gif int  length(link s) /**//*---length---求链的长度*/
 43ExpandedSubBlockStart.gifContractedSubBlock.gif    int i=0;/**//*i不赋初值,编译错误“可能在i定义以前使用了它在length函数中”*/
 44    link p=NULL;
 45    p=s;
 46ExpandedSubBlockStart.gifContractedSubBlock.gif    while(p->next!=NULL){
 47        p=p->next;
 48        i++;
 49    }

 50    return i;
 51}

 52
 53
 54 ExpandedBlockStart.gifContractedBlock.gif void  print(linklist l) {     /**//*---print---在屏幕上输出链表的所有元素*/
 55    link p=NULL;
 56    p=l.head;
 57ExpandedSubBlockStart.gifContractedSubBlock.gif    if(!p->next){
 58        printf("\nThe linklist is empty.\n\n");
 59        return ;
 60    }

 61    printf("The list:");
 62ExpandedSubBlockStart.gifContractedSubBlock.gif    while(p){
 63        printf("%c-",p->data);
 64        p=p->next;
 65    }

 66}

 67
 68
 69
 70 ExpandedBlockStart.gifContractedBlock.gif /**/ /*======================================================*/
 71 ExpandedBlockStart.gifContractedBlock.gif /**/ /*==========对带头结点的单链线性表进行操作的函数的定义==================*/
 72 ExpandedBlockStart.gifContractedBlock.gif /**/ /*======================================================*/
 73
 74 ExpandedBlockStart.gifContractedBlock.gifposition makenode( char  e) {       /**//*---分配由p指向的结点并赋值为e---*/
 75    link p=NULL;
 76    p=(link)malloc(sizeof(struct lnode));
 77ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*---struct lnode 才能表示一个结构体类型并可用于分配空间的元素类型定义-*/
 78ExpandedSubBlockStart.gifContractedSubBlock.gif    if(p){
 79        p->data=e;
 80        p->next=NULL;
 81    }

 82    else return;
 83    return p;
 84}

 85
 86
 87 ExpandedBlockStart.gifContractedBlock.gif void  freenode(link p) {          /**//*---释放p所指向的结点-*/
 88    free(p);
 89}

 90
 91
 92
 93 ExpandedBlockStart.gifContractedBlock.gif int  initlist(linklist  * l) {      /**//*---构造一个由l指向的空的线性表-*/
 94    l->head=makenode('L');
 95ExpandedSubBlockStart.gifContractedSubBlock.gif    l->head->next=NULL;/**//*不是l->head=NULL*/
 96    l->tail=l->head;
 97    l->len=0;
 98    return 1;
 99}

100
101
102 ExpandedBlockStart.gifContractedBlock.gifposition 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 ExpandedBlockStart.gifContractedBlock.gif int  insfirst(linklist  * l,link s) {    /**//*---将s指向的结点插入线性链表的第一个结点之前-*/
112    s->next=l->head->next;
113ExpandedSubBlockStart.gifContractedSubBlock.gif    if(!l->head->next) l->tail=s;/**//*当向一个空的线性表执行该操作时*/
114    l->head->next=s;
115    l->len++;
116
117}

118
119
120 ExpandedBlockStart.gifContractedBlock.gif int  append(linklist  * l,link s) {  /**//*---将指针s所的一串结点链接在线性表L的最后一个结点-*/
121    link q;
122    q=l->head;
123ExpandedSubBlockStart.gifContractedSubBlock.gif    if(!l->tail){/**//*考虑到链表为空的情况*/
124        l->head->next=s;
125ExpandedSubBlockStart.gifContractedSubBlock.gif        while(q->next) q=q->next;/**//*尾结点的处理*/
126        l->tail=q;
127    }

128    l->tail->next=q=s;
129ExpandedSubBlockStart.gifContractedSubBlock.gif    while(q->next) q=q->next;/**//*不能忘了对尾结点的处理*/
130    l->tail=q;
131    l->len+=length(s);
132
133}

134
135 ExpandedBlockStart.gifContractedBlock.gifposition delfirst(linklist  * l,link q) {    /**//*---删除表中第一个结点并以q返回-*/
136ExpandedSubBlockStart.gifContractedSubBlock.gif    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 ExpandedBlockStart.gifContractedBlock.gifposition remonode(linklist  * l,link q) {   /**//*---删除线性表l中的尾结点-*/
147ExpandedSubBlockStart.gifContractedSubBlock.gif    if(!l->tail){
148        printf("\nthe linklist is empty,can not remonde..\n");
149        return 0;
150    }

151ExpandedSubBlockStart.gifContractedSubBlock.gif    q=l->tail;                      /**//*用书上函数名remove时,编译错误“调用参数个数出错”*/
152    l->tail=priorpos(*l,q);
153    l->tail->next=NULL;
154    return q;
155}

156
157
158 ExpandedBlockStart.gifContractedBlock.gif 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 ExpandedBlockStart.gifContractedBlock.gif int  insafter(link p,link s) {    /**//*---将s所指向结点插入在p所指结点之后-*/
167    s->next=p->next;
168    p->next=s;
169}

170
171
172 ExpandedBlockStart.gifContractedBlock.gif int  setcurelem(link p, char  e) {         /**//*---用e更新p所指向的当前结点-*/
173    p->data=e;
174}

175
176
177 ExpandedBlockStart.gifContractedBlock.gif char  getcurelem(link p) {        /**//*---返回p所指结点中元素的值-*/
178    return p->data;
179}

180
181
182 ExpandedBlockStart.gifContractedBlock.gif int  listempty(linklist l) {         /**//*---若线性表为空表则返回1,否则返回0-*/
183    if(l.head==l.tail) return 1;
184    return 0;
185}

186
187
188 ExpandedBlockStart.gifContractedBlock.gif int  listlength(linklist l) {      /**//*---返回线性表中元素个数-*/
189    return l.len;
190}

191
192
193 ExpandedBlockStart.gifContractedBlock.gifposition gethead(linklist l) {     /**//*---返回线性表l中头结点的位置-*/
194    return l.head;
195}

196
197
198 ExpandedBlockStart.gifContractedBlock.gifposition getlast(linklist l) {      /**//*-----返回线性表l中最后一个结点的位置-------*/
199    return l.tail;
200}

201
202
203 ExpandedBlockStart.gifContractedBlock.gifposition nextpos(link p) {     /**//*-----返回p所指结点的直接后继的位置-------*/
204    link q;
205    q=p->next;
206    return q;
207}

208
209
210 ExpandedBlockStart.gifContractedBlock.gifposition  locatepos(linklist l, int  i,link p) {    /**//*-----用p返回线性表l中第i个结点的位置,并返回ok-------*/
211    p=l.head;
212    if(i<=0||i>listlength(l))   return 0;
213ExpandedSubBlockStart.gifContractedSubBlock.gif    while(i){
214        p=p->next;
215        i--;
216    }

217    return p;
218}

219         
220
221 ExpandedBlockStart.gifContractedBlock.gif int  locatelem(linklist l, char  e) {     /**//*----返回表中第一个与e满足一定函数关系的结点次序位置--------*/
222    int i=0;
223    link p;
224    p=l.head->next;
225ExpandedSubBlockStart.gifContractedSubBlock.gif    while(compare(p->data,e)&&p){
226        p=p->next;
227        ++i;
228    }

229ExpandedSubBlockStart.gifContractedSubBlock.gif    if(!p){/**//*考虑到查找不到指定元素的情况*/
230        printf("\nthere's no '%c' in this linklist.",e);
231        return 0;
232    }

233    return i;
234}

235
236
237 ExpandedBlockStart.gifContractedBlock.gif 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 ExpandedBlockStart.gifContractedBlock.gif int  clearlist(linklist * l) {      /**//*----?------将线性表l置为空表,并释放原链表的结点?*/
250    link p;
251    p=(*l).tail;
252ExpandedSubBlockStart.gifContractedSubBlock.gif    while(p!=(*l).head){
253        p=priorpos(*l,p);
254        freenode(p->next);
255    }

256    freenode((*l).head);
257
258}

259
260 ExpandedBlockStart.gifContractedBlock.gif int  destroylist(linklist  * l) {   /**//*----------销毁由l指向的线性表---------*/
261    link p;
262    p=(*l).tail;
263ExpandedSubBlockStart.gifContractedSubBlock.gif    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 ExpandedBlockStart.gifContractedBlock.gif /**/ /*=======================================================*/
275 ExpandedBlockStart.gifContractedBlock.gif /**/ /*==================主函数部分===================*/
276 ExpandedBlockStart.gifContractedBlock.gif /**/ /*=======================================================*/
277 ExpandedBlockStart.gifContractedBlock.gifmain() {
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);
285ExpandedSubBlockStart.gifContractedSubBlock.gif         /**//*调用初始化函数,构造一个由l指向的线性链表*/
286         printf("l->head->data:%c     ",l->head->data);
287         print(*l);
288
289ExpandedSubBlockStart.gifContractedSubBlock.gif    for(i=1;i<=5;i++){
290ExpandedSubBlockStart.gifContractedSubBlock.gif        s=makenode(temp++);/**//*每次插入结点都要重新分配空间,否则无限循环*/
291        insfirst(l,s);
292ExpandedSubBlockStart.gifContractedSubBlock.gif         /**//*将s指向的结点插入在以(*l).head为头结点的链表的第一个元素之前*/
293    }

294    printf("insfirst(l,s)*5,   ");
295    print(*l);
296
297ExpandedSubBlockStart.gifContractedSubBlock.gif    s_nodes=s=makenode(temp++);/**//*_1_*/
298    printf("\ns_nodes:");
299ExpandedSubBlockStart.gifContractedSubBlock.gif    for(i=1;i<=NODE_NUM;i++){
300ExpandedSubBlockStart.gifContractedSubBlock.gif         s->next=makenode(temp++);/**//*_2_*/
301            printf("%c ",s->data);
302         s=s->next;
303ExpandedSubBlockStart.gifContractedSubBlock.gif    }
/**//*构造了一串由s_nodes指向的链,并为其中的数据项赋值*/
304
305    append(l,s_nodes);
306ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*将由s_nodes指向的一串结点附加到l指向的链表的后面*/
307        printf("\nappend(l,s_nodes),   ");
308        print(*l);
309
310ExpandedSubBlockStart.gifContractedSubBlock.gif    q=delfirst(l,q);/**//*---*/
311ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*删除以(*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);
317ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*删除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;
324ExpandedSubBlockStart.gifContractedSubBlock.gif    for(i=1;i<=5;++i){
325        p=p->next;
326ExpandedSubBlockStart.gifContractedSubBlock.gif    }
/**//*移动指针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);
332ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*将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);
341ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*将s指向的结点插入到p指向的结点之后*/
342        printf("\ninsafter(p,s),");
343        print(*l);
344
345    setcurelem(p,temp++);
346ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*将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));
353ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*在printf函数中调用getcurelem函数,返回n指向的结点的值*/
354    printf("the listlinks'length:%d\n",listlength(*l));
355ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*在pringf函数中调用listlength函数,返回当前链表的元素个数*/
356
357    printf("priorpos(list,p):%c\n",priorpos(*l,p)->data);
358ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*返回p所指结点的直接前驱的位置*/
359
360    printf("\nnextpos(p):%c\n",nextpos(p)->data);
361ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*返回p所指结点的直接后继的位置*/
362
363    print(*l);
364    printf("\nthe element 'e' located at position %d\n",locatelem(*l,'e'));
365ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*返回l所指向的链表中元素值为e的结点的位置*/
366    printf("the element 'i' located at position %d\n",locatelem(*l,'i'));
367ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*返回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");
374ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//*判断l指向的链表中是否全都不是大写字母*/
375
376
377ExpandedSubBlockStart.gifContractedSubBlock.gif/**//*=========表间操作=========*/
378
379
380
381
382
383getch();
384}

385
386
387

转载于:https://www.cnblogs.com/LinderMan/archive/2009/07/25/1530750.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值