不要忽视任何细节---C语言链表操作的教训
2012-09-19 23:07
369 查看
最近发现服务器上一些服务进程一直处于长时间高CPU状态,有些进程甚至要跑10分钟左右,跟踪了一下发现,问题出现在如23-28代码中:
出现问题的原因在于每次添加一个节点,都要遍历整个链表,在链表Node个数较少的情况下,不会出现问题,但是当Node个数达到万或者十万百万量级的时候,这样的操作是相当的耗时,当时写这个代码的时候就是图简单,因实际运行的环境中90%都是Node数量较少的情况,所以就直接写下了这么烂的代码,终于在遇到大数据量的情况,出现了问题。
解决办法有两个,如果不要求链表中的数据先进先出,可以是直接将新Node添加在表头,这时,只需要修改添加元素的函数就可以了,代码如下:
如果对链表元素顺序有要求的话,可以考虑记住链表最后一个元素的位置,这时需要重新设计链表结构,代码如下:
当然,以上的代码只是大概表现了添加链表元素的操作,如需要从链表中取出元素,也要根据每种方法的特殊性考虑各自的细节,特别是在多线程中,链表操作会变得更加复杂。
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct LIST { int nValue; struct LIST *ptNext; }List; void Add2List(List **ptList, int nValue) { List *ptNew = (List *)calloc(1, sizeof(List)); ptNew->nValue = nValue; if(NULL == *ptList) { (*ptList) = ptNew; } else { //找到最后一个节点,将新节点放在这个节点之后 List *ptTemp = (*ptList); while(ptTemp->ptNext) { ptTemp = ptTemp->ptNext; } ptTemp->ptNext = ptNew; } } int main() { List *ptList = NULL; Add2List(&ptList, 1); Add2List(&ptList, 2); return 0; }
出现问题的原因在于每次添加一个节点,都要遍历整个链表,在链表Node个数较少的情况下,不会出现问题,但是当Node个数达到万或者十万百万量级的时候,这样的操作是相当的耗时,当时写这个代码的时候就是图简单,因实际运行的环境中90%都是Node数量较少的情况,所以就直接写下了这么烂的代码,终于在遇到大数据量的情况,出现了问题。
解决办法有两个,如果不要求链表中的数据先进先出,可以是直接将新Node添加在表头,这时,只需要修改添加元素的函数就可以了,代码如下:
//直接添加在链表头 void Add2List(List **ptList, int nValue) { List *ptNew = (List *)calloc(1, sizeof(List)); ptNew->nValue = nValue; ptNew->ptNext = *ptList; *ptList= ptNew; }
如果对链表元素顺序有要求的话,可以考虑记住链表最后一个元素的位置,这时需要重新设计链表结构,代码如下:
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct NODE { int nValue; struct NODE *ptNext; }Node; typedef struct LIST { Node *ptLast; Node *ptList; }List; void Add2List(List **ptList, int nValue) { Node *ptNew = (Node *)calloc(1, sizeof(Node)); ptNew->nValue = nValue; if(NULL == *ptList) { (*ptList) = (List *)calloc(1, sizeof(List)); (*ptList)->ptLast = (*ptList)->ptList = ptNew; } else { (*ptList)->ptLast->ptNext = ptNew; (*ptList)->ptLast = ptNew; } } int main() { List *ptList = NULL; Add2List(&ptList, 1); Add2List(&ptList, 2); return 0; }
当然,以上的代码只是大概表现了添加链表元素的操作,如需要从链表中取出元素,也要根据每种方法的特殊性考虑各自的细节,特别是在多线程中,链表操作会变得更加复杂。
相关文章推荐
- c语言链表操作
- 关于C语言的指针、链表的原理和各类操作
- C语言单链表基本操作
- 双向循环链表基本操作的实现(C语言)
- 教训:误执行drop user user_name cascade; 后,请立即保护现场--禁止再对该db执行任何写入性的操作。
- C语言链表常见基本操作
- C语言的指针、链表的原理和各类操作
- 单链表及其基本操作(C语言实现)
- 链表的实现与操作(C语言实现)
- 转贴:C语言链表基本操作
- 单链表(C语言)基本操作
- 2.简单链表操作_C语言
- C语言---双向链表的插入、删除、查找操作
- C语言链表的基本操作
- c语言链表的基本操作2
- 不要忽视Web编程中的小细节
- c语言链表操作
- C语言 链表的基本操作实现 源码
- c语言 双向链表的基础操作
- C语言----链表的各项操作总结----单项循环链表