单链表的操作

题目:单链表的插入和删除

目的

了解和掌握线性表的逻辑结构和链式存储结构,掌握单链表的基本算法及相关的时间性能分析。

要求:

建立一个数据域定义为字符串的单链表,在链表中不允许有重复的字符串;根据输入的字符串,先找到相应的结点,后删除之。

 

实验主要步骤:

1、分析、理解给出的示例程序。

2、调试程序,并设计输入数据(如:bat,cat,eat,fat,hat,jat,lat,mat,#),测试程序的如下功能:不允许重复字符串的插入;根据输入的字符串,找到相应的结点并删除。

3、修改程序:

(1)       增加插入结点的功能。

(2)       将建立链表的方法改为头插入法。

 

  1 #include"stdio.h"
  2 
  3 #include"string.h"
  4 
  5 #include"stdlib.h"
  6 
  7 #include"ctype.h"
  8 
  9 typedef struct node          //定义结点
 10 
 11 {
 12 
 13        char data[10];             //结点的数据域为字符串
 14 
 15        struct node *next;      //结点的指针域
 16 
 17 }ListNode;
 18 
 19 typedef ListNode * LinkList;         // 自定义LinkList单链表类型
 20 
 21 LinkList CreatListR1();              //函数,用尾插入法建立带头结点的单链表
 22 
 23 LinkList CreatList(void);            //函数,用头插入法建立带头结点的单链表
 24 
 25 ListNode *LocateNode(LinkList head, char *key);   //函数,按值查找结点
 26 
 27 void DeleteList(LinkList head,char *key) ;                 //函数,删除指定值的结点
 28 
 29 void printlist(LinkList head);                   //函数,打印链表中的所有值
 30 
 31 void DeleteAll(LinkList head);                   //函数,删除所有结点,释放内存
 32 
 33 ListNode * AddNode(LinkList head);                      //修改程序:增加节点。用头插法,返回头指针
 34 
 35  
 36 
 37 //==========主函数==============
 38 
 39  
 40 
 41 void main()
 42 
 43 {
 44 
 45        char ch[10],num[5];
 46 
 47        LinkList head;
 48 
 49        head=CreatList();          //用头插入法建立单链表,返回头指针
 50 
 51        printlist(head);             //遍历链表输出其值
 52 
 53        printf(" Delete node (y/n):");  //输入"y"或"n"去选择是否删除结点
 54 
 55        scanf("%s",num);
 56 
 57        if(strcmp(num,"y")==0 || strcmp(num,"Y")==0){
 58 
 59               printf("Please input Delete_data:");
 60 
 61               scanf("%s",ch);              //输入要删除的字符串
 62 
 63               DeleteList(head,ch);
 64 
 65               printlist(head);
 66 
 67        }
 68 
 69        printf(" Add node ? (y/n):");  //输入"y"或"n"去选择是否增加结点
 70 
 71        scanf("%s",num);
 72 
 73        if(strcmp(num,"y")==0 || strcmp(num,"Y")==0)
 74 
 75        {
 76 
 77               head=AddNode(head);
 78 
 79        }
 80 
 81  
 82 
 83        printlist(head);
 84 
 85        DeleteAll(head);            //删除所有结点,释放内存
 86 
 87 }
 88 
 89 //==========用尾插入法建立带头结点的单链表===========
 90 
 91 LinkList CreatListR1(void)
 92 
 93 {
 94 
 95     char ch[10];
 96 
 97     LinkList head=(LinkList)malloc(sizeof(ListNode)); //生成头结点
 98 
 99     ListNode *s,*r,*pp;
100 
101     r=head;
102 
103     r->next=NULL;
104 
105     printf("Input # to end  ");  //输入"#"代表输入结束
106 
107     printf("\nPlease input Node_data:");
108 
109     scanf("%s",ch);           //输入各结点的字符串
110 
111  
112 
113     while(strcmp(ch,"#")!=0) {        
114 
115               pp=LocateNode(head,ch);      //按值查找结点,返回结点指针
116 
117              
118 
119               if(pp==NULL) {            //没有重复的字符串,插入到链表中
120 
121                      s=(ListNode *)malloc(sizeof(ListNode));
122 
123                      strcpy(s->data,ch);
124 
125  
126 
127                      r->next=s;
128 
129                      r=s;
130 
131                      r->next=NULL;
132 
133               }
134 
135               printf("Input # to end  ");
136 
137               printf("Please input Node_data:");
138 
139               scanf("%s",ch);
140 
141     }
142 
143     return head;        //返回头指针
144 
145 }
146 
147  
148 
149 //==========用头插入法建立带头结点的单链表===========
150 
151 LinkList CreatList(void)
152 
153 {
154 
155        char ch[100];
156 
157        LinkList head,p;
158 
159        head=(LinkList)malloc(sizeof(ListNode));
160 
161        head->next=NULL;
162 
163  
164 
165        while(1)
166 
167        {
168 
169               printf("Input # to end  "); 
170 
171               printf("Please input Node_data:");
172 
173               scanf("%s",ch);          
174 
175               if(strcmp(ch,"#"))
176 
177               {      
178 
179                      if(LocateNode(head,ch)==NULL)
180 
181                      {  
182 
183                             strcpy(head->data,ch);
184 
185                             p=(LinkList)malloc(sizeof(ListNode));
186 
187                             p->next=head;
188 
189                             head=p;
190 
191                      }
192 
193               }
194 
195               else
196 
197                      break;
198 
199        }
200 
201        return head;       
202 
203 }
204 
205  
206 
207 //==========按值查找结点,找到则返回该结点的位置,否则返回NULL==========
208 
209 ListNode *LocateNode(LinkList head, char *key)
210 
211 {
212 
213     ListNode *p=head->next; //从开始结点比较
214 
215     while(p!=NULL && strcmp(p->data,key)!=0)  //直到p为NULL或p->data为key止
216 
217               p=p->next;        //扫描下一个结点
218 
219     return p;    //若p=NULL则查找失败,否则p指向找到的值为key的结点
220 
221 }
222 
223  
224 
225 //==========修改程序:增加节点=======
226 
227 ListNode * AddNode(LinkList head)
228 
229 {
230 
231     char ch[10];
232 
233        ListNode *s,*pp;
234 
235  
236 
237     printf("\nPlease input a New Node_data:");
238 
239     scanf("%s",ch);           //输入各结点的字符串
240 
241  
242 
243        pp=LocateNode(head,ch);      //按值查找结点,返回结点指针
244 
245        printf("ok2\n");     
246 
247  
248 
249        if(pp==NULL) {            //没有重复的字符串,插入到链表中
250 
251               s=(ListNode *)malloc(sizeof(ListNode));
252 
253               strcpy(s->data,ch);
254 
255               printf("ok3\n");
256 
257  
258 
259               s->next=head->next;
260 
261               head->next=s;
262 
263        }
264 
265  
266 
267        return head;
268 
269  
270 
271 }
272 
273  
274 
275 //==========删除带头结点的单链表中的指定结点=======
276 
277 void DeleteList(LinkList head,char *key)
278 
279 {
280 
281     ListNode *p,*r,*q=head;
282 
283     p=LocateNode(head,key);    //按key值查找结点的
284 
285     if(p==NULL ) {            //若没有找到结点,退出
286 
287               printf("position error");
288 
289               exit(0);
290 
291     }
292 
293     while(q->next!=p)        //p为要删除的结点,q为p的前结点
294 
295               q=q->next;
296 
297     r=q->next;
298 
299     q->next=r->next;
300 
301     free(r);                //释放结点
302 
303 }
304 
305 //===========打印链表=======
306 
307 void printlist(LinkList head)
308 
309 {
310 
311     ListNode *p=head->next;       //从开始结点打印
312 
313     while(p){
314 
315               printf("%s,   ",p->data);
316 
317               p=p->next;
318 
319     }
320 
321     printf("\n");
322 
323 }
324 
325 //==========删除所有结点,释放空间===========
326 
327 void DeleteAll(LinkList head)
328 
329 {
330 
331     ListNode *p=head,*r;
332 
333     while(p->next){
334 
335               r=p->next;
336 
337               free(p);
338 
339               p=r;
340 
341        }
342 
343        free(p);
344 
345 }

 

 

实验结果:

Input # to end  Please input Node_data:bat

Input # to end  Please input Node_data:cat

Input # to end  Please input Node_data:eat

Input # to end  Please input Node_data:fat

Input # to end  Please input Node_data:hat

Input # to end  Please input Node_data:jat

Input # to end  Please input Node_data:lat

Input # to end  Please input Node_data:mat

Input # to end  Please input Node_data:#

mat,   lat,   jat,   hat,   fat,   eat,   cat,   bat,

 Delete node (y/n):y

Please input Delete_data:hat

mat,   lat,   jat,   fat,   eat,   cat,   bat,

 Insert node (y/n):y

Please input Insert_data:put

position :5

mat,   lat,   jat,   fat,   eat,   put,   cat,   bat,

请按任意键继续. . .

 

posted @ 2019-04-30 09:54  晓不小QAQ  阅读(538)  评论(0编辑  收藏  举报