顺序表和链表的比较
常见的链表:
单链表、循环链表、双向链表
单链表的实现方式:
typedef struct LNode{
ElemType data;
struct LNode *next;
}LNode,*LinkList;
LinkList L;
循环链表的实现代码
和单链表实现方式相同。区别是:循环链表的最后一个元素的next域指向头结点。一般循环链表设置尾指针,因为比较容易实现链表的尾指针的查询操作。
R->next=L;
双向链表的实现代码
typedef struct DuLNode{
ElemType data;
struct DuLNode *prior,*next;
}DuLNode,*DuLinkList;
双向循环链表的实现代码
和双向链表的实现方式相同。区别是:双向循环链表的最后一个元素的next域指向头结点,头结点的prior域指向最后一个元素。也是一般设置尾结点。
L->prior=R;
R->next=L;
常见链表的时间效率比较
查找表头结点(首元结点) | 查找表尾结点 | 查找结点*p的前驱结点 | |
---|---|---|---|
带头结点的单链表L | L->next 时间复杂度O(1) | 从L->next依次向后遍历 时间复杂度O(n) | 通过p->next无法找到其前驱 |
带头结点仅有头指针L的循环单链表 | L->next 时间复杂度O(1) | 从L->next依次向后遍历 时间复杂度O(n) | 通过p->next可以找到其前驱 时间复杂度O(n) |
带头结点仅有尾指针R的循环单链表 | R->next 时间复杂度O(1) | R 时间按复杂度O(1) | 通过p->next可以找到其前驱 时间复杂度O(n) |
带头结点的双向循环链表L | L->next 时间复杂度O(1) | L->prior 时间复杂度O(1) | L->prior 时间复杂度O(1) |
- 双向循环链表用空间来换取了时间。
顺序表和链表的比较
链式存储结构的优缺点
-
链式存储结构的优点:
1.结点空间可以动态申请和释放
2.数据元素的逻辑次序靠结点的指针来指示,插入和删除不需要移动元素 -
链式存储结构的缺点:
1.链式存储结构是非随机存取结构
2.存储密度1小,每个结点的指针域需额外占用存储空间,当每个结点的数据域所占字节不多时,指针域所占存储空间的比重显得很大
顺序表与链表的比较
存储密度是指结点数据本身所占的存储量和整个节点结构中所占的存储量之比,即:
存储密度 = = = 结 点 数 据 本 身 占 用 的 空 间 结 点 占 用 的 总 空 间 \dfrac{结点数据本身占用的空间}{结点占用的总空间} 结点占用的总空间结点数据本身占用的空间 ↩︎