修改了代码,重新放上来以作记录:
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct stu 4 { 5 int num; 6 float score; 7 }datatype; 8 typedef struct student 9 { 10 datatype data; 11 struct student * next; 12 }LNode; 13 int N=0; 14 15 LNode *creat(int n); 16 void out(LNode *head); 17 void myFree(LNode *head); 18 LNode *insert(LNode *head,LNode *p,datatype e); 19 //插入一个新的节点到节点p之前。假如找不到p节点则插入到链表末尾。新节点数据域由e来构成。 20 void insert2(datatype e,LNode *q); 21 //在节点q之后插入新的节点p .p的数据由e来构造 22 void delElem(LNode *head,datatype e);//【本算法有缺陷】删除以head为头结点的链表中数据等于e的节点 23 LNode *delElem2(LNode *head,datatype e);//删除链表中值为e的节点,返回头结点 24 int cmp(datatype a,datatype b);//比较a和b是否相等 25 int main() 26 { 27 LNode *head; 28 datatype a,b,c; 29 freopen("5.in","r",stdin); 30 31 c.num=4; 32 c.score=800; 33 b.num=5; 34 b.score=900; 35 a.num=6; 36 a.score=600; 37 38 head=creat(3); 39 printf("creat main:%d\n",N); 40 out(head); 41 42 head=insert(head,head->next->next,c); 43 printf("insert to 3th:%d\n",N); 44 out(head); 45 46 head=insert(head,head,b); 47 printf("insert to head:%d\n",N); 48 out(head);/**/ 49 50 insert2(a,head); 51 printf("insert2 to second:%d\n",N); 52 out(head);/**/ 53 54 delElem(head,a); 55 printf("delElem 6:%d\n",N); 56 out(head);/**/ 57 58 delElem(head,b); 59 printf("delElem 5:%d\n",N); 60 out(head);/**/ 61 62 myFree(head); 63 printf("after free all:%d\n",N);/**/ 64 return 0; 65 } 66 LNode *creat(int n) 67 { 68 LNode *head,*p,*end; 69 int i; 70 for(i=1;i<=n;i++) 71 { 72 p=(LNode*) malloc(sizeof(LNode)); 73 p->next=NULL; 74 //printf("input student %d information:\n",i); 75 scanf("%d%f",&(p->data.num),&(p->data.score)); 76 if(i==1) 77 { 78 head=p; 79 end=p; 80 } 81 else 82 { 83 end->next=p; 84 end=p; 85 } 86 N++; 87 } 88 return(head); 89 } 90 void out(LNode *head) 91 { 92 LNode *p; 93 p=head; 94 while(p) 95 { 96 printf("%d %f\n",p->data.num,p->data.score); 97 p=p->next; 98 } 99 } 100 void myFree(LNode *head) 101 { 102 LNode *p; 103 do 104 { p=head->next; 105 free(head); 106 N--; 107 head=p; 108 }while(head); 109 } 110 LNode *insert(LNode *head,LNode *p,datatype e) 111 //在以head为头结点的链表中插入一个新的节点到节点p之前。假如找不到p节点则插入到链表末尾。新节点数据域由e来构成。 112 { 113 LNode *t,*q,temp; 114 115 q=(LNode *)malloc(sizeof(LNode)); 116 q->data=e; 117 q->next=NULL; 118 119 if(head==p) 120 { 121 q->next=head; 122 head=q; 123 } 124 else 125 { 126 t=head; 127 while(t->next!=p&&t->next!=NULL) 128 { 129 t=t->next; 130 } 131 if(t->next==p) 132 { 133 t->next=q; 134 q->next=p; 135 } 136 else 137 { 138 t->next=q; 139 q->next=NULL; 140 } 141 } 142 N++; 143 return head; 144 } 145 void insert2(datatype e,LNode *q) 146 //在节点q之后插入新的节点p .p的数据由e来构造 147 { 148 LNode *p; 149 p=(LNode *)malloc(sizeof(LNode)); 150 p->data=e; 151 p->next=NULL; 152 153 p->next=q->next; 154 q->next=p; 155 N++; 156 } 157 void delElem(LNode *head1,datatype e)//删除以head为头结点的链表中数据等于e的节点 158 /*下面做个算法有一个漏洞:当链表里面所有节点值都相等且等于e, 159 则会在下面第一个while出现问题:当p->next为NULL,则p=p->next;之后 160 再执行head1->num=p->num;会出错。*/ 161 { 162 LNode *t,*p; 163 p=head1; 164 while(p!=NULL&&cmp(p->data,e)==1)//头结点及其后面连续的若干个的值可能等于e。把这些都删掉。 165 { 166 p=p->next; 167 head1->data=p->data; 168 head1->next=p->next; 169 free(p); 170 N--; 171 } 172 if(p!=NULL) 173 { 174 t=p; 175 p=p->next; 176 while(p!=NULL) 177 { 178 if(cmp(p->data,e)==1)//判断p的数据是否等于要删除的数据 179 {//下面删掉p节点并把p指向下一个节点 180 t->next=p->next; 181 free(p); 182 N--; 183 p=t->next; 184 } 185 else 186 {//t和p都向后移动一个节点 187 t=t->next; 188 p=p->next; 189 } 190 } 191 } 192 } 193 LNode *delElem2(LNode *head1,datatype e) 194 //删除链表中值为e的节点,返回头结点 195 { 196 LNode *t,*p; 197 while(head1!=NULL&&cmp(head1->data,e)==1)//头结点及其后面连续的若干个的值可能等于e。把这些都删掉。 198 { 199 p=head1; 200 head1=head1->next; 201 free(p); 202 N--; 203 } 204 p=head1; 205 while(p!=NULL) 206 { 207 if(cmp(p->data,e)==1) 208 { 209 t=p; 210 p=p->next; 211 free(t); 212 N--; 213 } 214 else 215 { 216 p=p->next; 217 } 218 } 219 return head1; 220 } 221 int cmp(datatype a,datatype b) 222 { 223 if(a.num==b.num&&a.score==b.score) return 1; 224 else return 0; 225 }
注意:释放链表时,假如有些节点是变量,不是malloc动态分配的内存,对他们释放内存会出错的。所以下面代码中main函数当中作为测试用的几个节点都是malloc出来的。
修改前的代码,不太好,先存着(下面的不用看了)
1 #include<stdio.h> 2 #include<stdlib.h> 3 typedef struct student 4 { 5 int num; 6 float score; 7 struct student * next; 8 }LNode; 9 int N=0; 10 11 LNode *creat(int n); 12 void out(LNode *head); 13 void myFree(LNode *head); 14 LNode *insert(LNode *head,LNode *p,LNode *q); 15 //在以head为头结点的链表中插入一个新的节点p到节点q之前。 假如找不到q节点则把p插入到链表末尾。 16 void insert2(LNode *p,LNode *q); 17 //在节点q之后插入新的节点p 18 void delElem(LNode *head,LNode *p);//删除以head为头结点的链表当中的节点p 19 int main() 20 { 21 LNode *head,*a,*b,*c; 22 freopen("5.in","r",stdin); 23 24 a=(LNode*)malloc(sizeof(LNode)); 25 b=(LNode*)malloc(sizeof(LNode)); 26 c=(LNode*)malloc(sizeof(LNode)); 27 28 c->num=4; 29 c->score=800; 30 c->next=NULL; 31 32 b->num=5; 33 b->score=900; 34 b->next=NULL; 35 36 a->num=6; 37 a->score=600; 38 a->next=NULL; 39 40 head=creat(3); 41 printf("creat main:%d\n",N); 42 out(head); 43 44 head=insert(head,c,head->next->next); 45 printf("insert to 3th:%d\n",N); 46 out(head); 47 48 head=insert(head,b,head); 49 printf("insert to head:%d\n",N); 50 out(head);/**/ 51 52 insert2(a,head); 53 printf("insert2 to second:%d\n",N); 54 out(head);/**/ 55 56 delElem(head,head->next); 57 printf("delElem second:%d\n",N); 58 out(head);/**/ 59 60 delElem(head,head); 61 printf("delElem first:%d\n",N); 62 out(head);/**/ 63 64 myFree(head); 65 printf("after free all:%d\n",N);/**/ 66 return 0; 67 } 68 LNode *creat(int n) 69 { 70 LNode *head,*p,*end; 71 int i; 72 for(i=1;i<=n;i++) 73 { 74 p=(LNode*) malloc(sizeof(LNode)); 75 p->next=NULL; 76 //printf("input student %d information:\n",i); 77 scanf("%d%f",&(p->num),&(p->score)); 78 if(i==1) 79 { 80 head=p; 81 end=p; 82 } 83 else 84 { 85 end->next=p; 86 end=p; 87 } 88 N++; 89 } 90 return(head); 91 } 92 void out(LNode *head) 93 { 94 LNode *p; 95 p=head; 96 while(p) 97 { 98 printf("%d %f\n",p->num,p->score); 99 p=p->next; 100 } 101 } 102 void myFree(LNode *head) 103 { 104 LNode *p; 105 do 106 { p=head->next; 107 free(head); 108 N--; 109 head=p; 110 }while(head); 111 } 112 LNode *insert(LNode *head,LNode *p,LNode *q) 113 //在以head为头结点的链表中插入一个新的节点p到节点q之前。 假如找不到q节点则把p插入到链表末尾。 114 { 115 LNode *t; 116 if(head==q) 117 { 118 p->next=head; 119 head=p; 120 } 121 else 122 { 123 t=head; 124 while(t->next!=q&&t->next!=NULL) 125 { 126 t=t->next; 127 } 128 if(t->next==q) 129 { 130 t->next=p; 131 p->next=q; 132 } 133 else 134 { 135 t->next=p; 136 p->next=NULL; 137 } 138 } 139 N++; 140 return head; 141 /*out(head); 142 printf("insert:%d\n",N);*/ 143 } 144 void insert2(LNode *p,LNode *q) 145 //在节点q之后插入新的节点p 146 { 147 p->next=q->next; 148 q->next=p; 149 N++; 150 } 151 void delElem(LNode *head1,LNode *p)//删除以head为头结点的链表当中的节点p 152 { 153 LNode *q; 154 if(p==head1) 155 { 156 p=p->next; 157 head1->num=p->num; 158 head1->next=p->next; 159 free(p); 160 N--; 161 } 162 else 163 { 164 q=head1; 165 while(q->next!=p&&q->next!=NULL)//q节点的下一个不是p,q也不是末尾节点 166 { 167 q=q->next; 168 } 169 if(q->next!=NULL) 170 { 171 q->next=p->next; 172 free(p); 173 N--; 174 } 175 } 176 }