这是一个系列的文章,主要目的是让初学者掌握链表的实现方法,并且从C过渡到C++。
作者:重庆工程职业技术学院 万青
本文设计一个带头结点的单向链表。和很多教程不同的是,采用了结构体来存储链表的首、尾指针和长度,并把结构体命名为List:
typedef struct list { Node *head,*tail; int length; }List;
这样设计能很好地管理链表相关属性,并且在操作时能提供一些便利。下面的代码实现了链表的一些常用操作:
1 #include<stdio.h> 2 #include<malloc.h> 3 typedef struct node 4 { 5 int data; 6 struct node *next; 7 }Node; 8 9 //该结构用于管理链表的头、尾指针和长度 10 typedef struct list 11 { 12 Node *head,*tail; 13 int length; 14 }List; 15 16 List *create() 17 { 18 List *li; 19 Node *p; 20 li=(List *)malloc(sizeof(List)); 21 p=(Node *)malloc(sizeof(Node)); 22 li->head=li->tail=p; 23 li->tail->next=NULL; 24 li->length=0; 25 return li; 26 } 27 28 void add(int num,List *li) 29 { 30 Node *p; 31 p=(Node *)malloc(sizeof(Node)); 32 p->data=num; //给数据域赋值 33 li->tail->next=p; 34 li->tail=p;//调整尾指针,指向新节点 35 li->tail->next=NULL; //设置结束标志 36 li->length++; //节点总数加1 37 } 38 39 void show(List *li) 40 { 41 Node *p; 42 p=li->head; 43 while(p->next!=NULL) 44 { 45 p=p->next; //head节点没有数据,先移动再读取 46 printf("%d ",p->data); 47 } 48 printf("\n--------------\n"); 49 } 50 //idx从1开始,表示指向第1个有效节点 51 Node *getPointerByIdx(int idx,List *li) 52 { 53 Node *p; 54 int i=1; 55 if(idx<1 || idx>li->length) return NULL; 56 p=li->head; 57 /*while(i<=idx) 58 if(p->next!=NULL) 59 { 60 p=p->next; 61 i++; 62 } 63 else 64 { p=NULL; 65 break; 66 }*/ 67 while(i<=idx) 68 { 69 p=p->next; 70 i++; 71 } 72 return p; 73 } 74 75 int insert(int idx,int num,List *li) 76 { 77 Node *p,*tmp; 78 p=getPointerByIdx(idx,li); 79 if(p!=NULL) 80 { 81 tmp=(Node *)malloc(sizeof(Node)); 82 tmp->data=num; 83 tmp->next=p->next; 84 p->next=tmp; 85 li->length++; 86 return 1; /*成功,返回1*/ 87 } 88 return 0; /*失败,返回0*/ 89 } 90 91 int del(int idx,List *li) 92 { 93 Node *p,*q; 94 if(idx<1 || idx>li->length) 95 return 0; /*失败,返回0*/ 96 97 //获得要删除节点的前一个节点指针 98 if(idx==1) p=li->head; 99 else p=getPointerByIdx(idx,li); 100 101 //删除p节点的后一节点 102 q=p->next; //记住后一节点的指针 103 p->next=q->next; 104 free(q); 105 li->length--; 106 return 1;//成功,返回1 107 108 } 109 110 void clear(List *li) 111 { 112 Node *curr,*next; 113 curr=li->head; 114 while(curr->next!= NULL) 115 { 116 next=curr->next; 117 free(curr); 118 curr=next; 119 } 120 free(curr); 121 free(li); 122 } 123 124 void main() 125 { 126 List *li; 127 Node *nd; 128 li=create(); 129 add(100,li); 130 add(101,li); 131 add(102,li); 132 add(103,li); 133 show(li); 134 insert(2,200,li); //在位置2插入200 135 show(li); 136 insert(3,300,li); //在位置3插入300 137 show(li); 138 del(1,li); //删除第1个 139 show(li); 140 //nd=getPointerByIdx(3,li); 141 //printf("\n地址:%u\n",nd); 142 //printf("\n长度:%d",li->length); 143 clear(li); 144 }