C语言数组和链表删除元素速度比较
2016-10-15 21:30
393 查看
前断时间我做个实验对比了java数组和链表插入和删除元素时间对比,结果是数组完胜,后来发现不止我一个人得出了这样的结果[链接](http://blog.csdn.net/qq_21544879/article/details/51909473),今天用C语言再次做了数组和链表删除元素测试,结果没有给我惊喜,链表完胜。但也有一个新的发现,最初在删除数组元素时,我用for循环把数组元素一个个往前移,后来试了下按字节拷贝,最后还试了一下用系统的memcpy函数来往前移动数组元素。结果很是意外,memcpy也是按字节来拷贝的,按理说其速度应该与自己实现的按字节拷贝差不多,最后测试结果是**memcpy > for循环拷贝 > 自己实现按字节拷贝**。其速度相差都是好几倍,最后我对这三种方式拷贝数组做了测试,测试代码在下面。
贴下我的测试代码,欢迎指出错误:
实验一,数组和链表随机删除元素速度测试:
实验数据为20W个整数, 测试系统为ubuntu16.04, 先给数组和链表各填充20W个元素,然后随机删除元素,删除元素为随机数对数组或链表剩余元素数量取余,防止越界。
//测试结果 /* 线性表删除运行耗时26729 ms 链性表删除运行耗时0 ms 线性表删除运行耗时27650 ms 链性表删除运行耗时0 ms 线性表删除运行耗时26710 ms 链性表删除运行耗时0 ms 线性表删除运行耗时26828 ms 链性表删除运行耗时0 ms 线性表删除运行耗时26698 ms 链性表删除运行耗时0 ms */ #include <stdio.h> #include <malloc.h> #include <time.h> #include <stdlib.h> #include <assert.h> #include <time.h> #include <pthread.h> #include <unistd.h> #include <sys/time.h> #include <memory.h> #define SIZE 200000 //20W //链表节点 typedef struct LNode { int elem; struct LNode *next; } LNode; //链表 typedef struct { LNode *list; long length; }LinkList; //线性表 typedef struct { int *elems; long length; long listSize; }SqList; //初始化元素 void initSqList(SqList *sqList); void initLinkList(LinkList *linkList); //打印 void printSqlist(SqList *sqList); void printLinkList(LinkList *linkList); //删除 void sqListDel(SqList *sqList, long pos); void linkListDel(LinkList *linkList, long pos); //线性表和链表删除耗时比较 void delDiff(SqList *sqList, LinkList *linkList); //插入耗时比较 void insertDiff(SqList sqList, LinkList linkList); //线性表和链表随机删除和插入元素比较 int main() { LinkList *linkList = NULL; SqList *sqList = NULL; linkList = (LinkList *) malloc(sizeof(LinkList)); linkList->list = (LNode *) malloc(sizeof(LNode)); assert(linkList->list != NULL); linkList->list->next = NULL; sqList = (SqList *) malloc(sizeof(SqList)); if(!sqList || !linkList) { printf("分配空间失败"); return -1; } int i = 0; for(; i < 5; i++) { initSqList(sqList); /* printSqlist(sqList); */ initLinkList(linkList); /* printLinkList(linkList); */ delDiff(sqList, linkList); } return 0; } void initSqList(SqList *sqList) { assert(sqList != NULL); sqList->elems = (int *) malloc(sizeof(int) * SIZE); if(!sqList->elems) { printf("分配数组空间失败"); } long i = 0; for(; i < SIZE; i++) { sqList->elems[i] = i; } sqList->length = SIZE; sqList->listSize = SIZE; } void printSqlist(SqList *sqList) { assert(sqList != NULL); long i = 0; for(; i < sqList->length; i++) { printf("%d, ", sqList->elems[i]); } printf("打印完成\n"); } void initLinkList(LinkList *linkList) { assert(linkList != NULL && linkList -> list != NULL); LNode *tail = linkList->list; long i = 0; for(; i < SIZE; i++) { LNode *temp = (LNode *) malloc(sizeof(LNode)); temp->elem = i; tail->next = temp; tail = temp; } linkList->length = SIZE; } void printLinkList(LinkList *linkList) { assert(linkList != NULL && linkList->list != NULL); LNode *temp = linkList -> list; while(temp->next != NULL) { printf("%d, ", temp->next->elem); temp = temp->next; } printf("打印完成\n"); } void sqListDel(SqList *sqList, long pos) { assert(sqList != NULL && sqList->elems != NULL); if(pos < 0 || pos >= sqList->length) { printf("pos: %ld 超出界限\n", pos); return; } long i = pos; for(; i < sqList->length - 1; i++) { sqList -> elems[i] = sqList->elems[i + 1]; } sqList->length--; } void linkListDel(LinkList *linkList, long pos) { assert(linkList != NULL && linkList->list != NULL); if(pos < 0 || pos >= linkList->length) { printf("pos: %ld 超出界限\n", pos); return; } LNode *temp = linkList->list; long i = 0; for(; i < pos; i++) { temp = temp->next; } LNode *delNode = temp->next; temp->next = temp->next->next; free(delNode); linkList->length--; } void delDiff(SqList *sqList, LinkList *linkList) { struct timeval startTime, endTime; srand((unsigned)time(0)); long ran_num; long i = 0; gettimeofday(&startTime, NULL); for(; i < SIZE; i++) { ran_num = rand() % (SIZE - i); sqListDel(sqList, ran_num); } gettimeofday(&endTime, NULL); printf("线性表删除运行耗时%ld ms\n", (endTime.tv_sec * 1000 + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000)); gettimeofday(&startTime, NULL); for(; i < SIZE; i++) { ran_num = rand() % (SIZE - i); linkListDel(linkList, ran_num); } gettimeofday(&endTime, NULL); printf("链性表删除运行耗时%ld ms\n", (endTime.tv_sec * 1000 + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000)); }
实验二,数组拷贝元素测试:
/* 实验结果 for循环拷贝数组200000000个元素耗时1154 ms 字节拷贝数组200000000个元素耗时1764 ms memcpy拷贝数组200000000个元素耗时182 ms for循环拷贝数组200000000个元素耗时517 ms 字节拷贝数组200000000个元素耗时1764 ms memcpy拷贝数组200000000个元素耗时178 ms for循环拷贝数组200000000个元素耗时514 ms 字节拷贝数组200000000个元素耗时1771 ms memcpy拷贝数组200000000个元素耗时179 ms for循环拷贝数组200000000个元素耗时516 ms 字节拷贝数组200000000个元素耗时1770 ms memcpy拷贝数组200000000个元素耗时177 ms for循环拷贝数组200000000个元素耗时515 ms 字节拷贝数组200000000个元素耗时1777 ms memcpy拷贝数组200000000个元素耗时178 ms */ #include <stdio.h> #include <malloc.h> #include <time.h> #include <stdlib.h> #include <assert.h> #include <time.h> #include <pthread.h> #include <unistd.h> #include <sys/time.h> #include <memory.h> #define SIZE 200000000 //200M //线性表 typedef struct { int *elems; long length; long listSize; }SqList; //初始化元素 void initSqList(SqList *sqList); //打印 void printSqlist(SqList *sqList); void copyDiff(SqList *sqList); //三种拷贝方法 void copyByFor(SqList *star, SqList *end, int len); void copyByBit(SqList *star, SqList *end, int len); void copyByMem(SqList *star, SqList *end, int len); //线性表和链表随机删除和插入元素比较 int main() { SqList *sqList = NULL; sqList = (SqList *) malloc(sizeof(SqList)); if(!sqList) { printf("分配空间失败"); return -1; } initSqList(sqList); copyDiff(sqList); return 0; } void initSqList(SqList *sqList) { assert(sqList != NULL); sqList->elems = (int *) malloc(sizeof(int) * SIZE); if(!sqList->elems) { printf("分配数组空间失败"); } long i = 0; for(; i < SIZE; i++) { sqList->elems[i] = i; } sqList->length = SIZE; sqList->listSize = SIZE; } void printSqlist(SqList *sqList) { assert(sqList != NULL); long i = 0; for(; i < sqList->length; i++) { printf("%d, ", sqList->elems[i]); } printf("打印完成\n"); } void copyDiff(SqList *sqList) { struct timeval startTime, endTime; SqList *temp = (SqList *) malloc(sizeof(SqList)); temp->elems = (int *) malloc(sizeof(int) * SIZE); temp->length = SIZE; temp->listSize = SIZE; long i = 0; for(; i < 5; i++) { gettimeofday(&startTime, NULL); copyByFor(sqList, temp, sqList->length); gettimeofday(&endTime, NULL); printf("for循环拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000 + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000)); gettimeofday(&startTime, NULL); copyByBit(sqList, temp, sqList->length); gettimeofday(&endTime, NULL); printf("字节拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000 + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000)); gettimeofday(&startTime, NULL); copyByMem(sqList, temp, sqList->length); gettimeofday(&endTime, NULL); printf("memcpy拷贝数组%d个元素耗时%ld ms\n", SIZE, (endTime.tv_sec * 1000 + endTime.tv_usec / 1000 - startTime.tv_sec * 1000 - startTime.tv_usec / 1000)); puts(""); } } void copyByFor(SqList *star, SqList *end, int len) { assert(star != NULL && end != NULL && len > 0); int *from = star->elems; int *to = end->elems; long i = 0; for( ; i < len; i++ ) { to[i] = from[i]; } } void copyByBit(SqList *star, SqList *end, int len) { assert(star != NULL && end != NULL && len > 0); char *from, *to; from = (char *) star->elems; to = (char *) end->elems; long i = 0; len = len * sizeof(int); for(; i < len ; i++) { *to++ = *from++; } } void copyByMem(SqList *star, SqList *end, int len) { assert(star != NULL && end != NULL && len > 0); memcpy(end->elems, star->elems, len * sizeof(int)); }
相关文章推荐
- js中比较两个数组中是否含有相同的元素,可去重,可删除合并为新数组
- 链表的基本操作(创建,查找指定位置元素,删除指定元素,插入,倒置,去重,求集合的差,分别交换结点与交换结点值实现的冒泡排序,将两个有序链表合并成一个有序链表)c语言实现
- 链表元素的比较和删除
- 将两个数组中的元素有序存入到一个链表中(C语言)
- 链表元素的比较和删除
- php 数组删除特定元素以及比较两个数组的不同
- 使用链表,删除数组中的元素
- JavaScript 删除数组中一个元素--delete与赋值为undefined方法比较
- C语言进阶-第17讲:链表和数组的比较
- C语言单向动态链表程序,实现链表的建立,合并,重新排序,链表元素的插入与删除,以及根据元素成员的值进行元素删除。
- c语言心得-----数组中对元素的操作排序,查找,插入,和删除
- 从数组A中删除在数组B中存在的元素,用C语言实现
- 删除数组中的元素(链表)
- 【C语言】比较两个数组中是否有相同的元素
- C语言 链表 数据结构实验之链表七:单链表中重复元素的删除
- 题目:c语言,删除数组中指定的重复的元素
- 结构体与链表练习 删除数组中的元素
- C语言 删除数组 某个元素
- 【C语言】-单链表元素的添加、删除
- 《数据结构与算法——C语言描述》答案 3.16 删除链表中的重复元素