顺序表与链表是很是基本的数据结构,它们能够被统称为线性表。
线性表(Linear List)是由 n(n≥0)个数据元素(结点)a[0],a[1],a[2]…,a[n-1] 组成的有限序列。
顺序表和链表,是线性表的不一样存储结构。它们各自有不一样的特色和适用范围。针对它们各自的缺点,也有不少改进的措施。node
顺序表通常表现为数组,使用一组地址连续的存储单元依次存储数据元素,如图 1 所示。它具备以下特色:sql
#include <string.h> struct sqlist { int *items, size, capacity; sqlist():size(0), capacity(4) { // initial capacity = 4 items = new int[capacity]; } void doubleCapacity() { capacity *= 2; int* newItems = new int[capacity]; memcpy(newItems, items, sizeof(int)*size); delete[] items; items = newItems; } void add(int value) { if (size >= capacity) { doubleCapacity(); } items[size++] = value; } };
这个办法不可避免的会浪费一些内存,由于数组的容量老是倍增的。并且每次扩容的时候,都须要将旧的数据所有复制一份,确定会影响效率。不过实际上,这样作仍是直接使用链表的效率要高,具体缘由会在下一节进行分析。数组
链表,相似它的名字,表中的每一个节点都保存有指向下一个节点的指针,全部节点串成一条链。根据指针的不一样,还有单链表、双链表和循环链表的区分,如图 2 所示。
数据结构
#include <stdio.h> #include <time.h> struct node { int value; node *next; }; struct llist { node *head; void add(int value) { node *newNode = new node(); newNode->value = value; newNode->next = head; head = newNode; } }; int main() { int size = 100000; sqlist list1; llist list2; long start = clock(); for (int i = 0;i < size;i++) { list1.add(i); } long end = clock(); printf("sequence list: %d\n", end - start); start = clock(); for (int i = 0;i < size;i++) { list2.add(i); } end = clock(); printf("linked list: %d\n", end - start); return 0; }
在个人电脑上,链表的耗时大约是顺序表的 4~8 倍。会这样,是由于数组只须要不多的几回大块内存分配,而链表则须要不少次小块内存分配,内存分配操做相对是比较慢的,于是大大拖慢了链表的速度。这也是为何会出现内存池。指针
所以,链表并不像理论分析的那样美好,在实际应用中要受不少条件制约,通常状况下仍是安心用顺序表的好。code