线性表
参考《王道数据结构》
线性表是从数据结构三要素中的逻辑结构上进行划分的,常见的有物理结构上顺序存储的顺序表和链式存储的链表。常见的例子有栈,队列,串等。下文将根据408考纲内容进行讲解:
- 线性表的定义和基本操作
- 线性表的实现
顺序存储;链式存储;线性表的应用
线性表
线性表定义:具有相同数据类型的n个元素的有限集合
顺序表:
线性表的顺序存储,一组地址连续的存储单元,特点在于逻辑顺序与其物理顺序相同。具有随机存取的特性,即具有首地址和元素序号则可以在O(1)时间内找到指定元素。存储密度高。查找快,插入、删除费时间,要移动元素覆盖。c语言顺序表动态分配如下:
#define InitSize 100
typedef struct SeqList {
ElemType *data; // 指针当做数组访问,不熟悉的推荐翁恺老师的c语言教程和"c++ primer"
int MaxSize, length;
} SeqList;
SeqList L;
L.data = (ElemType*)malloc(sizeof(ElemType)*InitSize); // malloc
按位查找,随机存取O(1)
按值查找算法,从前至后遍历O(n)
插入算法,从最后面的元素往后面覆盖,产生空位,插入O(n)
删除算法,从删除位置将后面元素覆盖上来O(n)
链表:
线性表的链式存储,逻辑上相邻的元素物理上不一定相邻。不具有随机存取特性。需要存储指向其他结点指针,存储密度下降。查找慢,插入、删除时间也主要消耗在查找上。
对于链表的算反,可以巧妙使用双指针法找到中端位置。可以使用标记数组法找到特定元素出现次数。可以用头插法实现原地逆置等。
c语言链表头插法创建如下:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode, *LinkList; // LinkList是头结点的类型 = struct LNode *的类型
/// 头插法创建单链表可以用来实现链表的原地逆置
LinkList ListHeadInsert(LinkList *L){
LNode *s; int x;
*L = (LinkList)malloc(sizeof(LNode)); // 注意指针大小同int大小,和CPU以及编译器有关,如x86就是32bit,64就是64bit
scanf("%d", &x);
while(x!=9999){
s = (LNode*)malloc(sizeof(LNode));
s->data = x;
s->next = L->next;
L->next = s;
scanf("%d", &x);
}
return L;
}
双链表,循环链表,静态链表(使用数组实现,并没有使用链)原理类似。