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

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

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

 40
 41
 42int 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
 54void 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
 74position 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
 87void freenode(link p){          /*---释放p所指向的结点-*/
 88    free(p);
 89}

 90
 91
 92
 93int 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
102position 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
111int 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
120int 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
135position 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
146position 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
158int 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
166int insafter(link p,link s){    /*---将s所指向结点插入在p所指结点之后-*/
167    s->next=p->next;
168    p->next=s;
169}

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

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

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

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

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

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

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

208
209
210position  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
221int 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
237int 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
249int 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
260int 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/*=======================================================*/
277main(){
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
383getch();
384}

385
386
387
posted @ 2009-07-25 10:11  林田惠  阅读(538)  评论(1编辑  收藏  举报


.
    ;  `┣━┒ ; `.┣─┒`   . .   ;   `.        
   .┟━┃┍╄┓┟━│ ╃━  `     、.    
` ┝─┃┣╈┤┣━┃;/ ╈ ╰⌒ˋのˊ  
 . ┗━┘┗┸┛└━┛/┃┻ `.   ′ ˋ `