目录
1. 循环链表
1.1 基本概念与尾指针
注意:在循环链表中,通过判定p是否等于头指针,来得到是否到达了链表的末尾。
如p=L或p->next=L
尾指针R
使用尾指针时,即使是操作尾结点,也不用从头开始找,时间复杂度仅为O(1)
1.2 循环链表的合并
思路
代码
Linklist connect(Linklist Ta, Linklist Tb){
Lnode *p = Ta->next;
Ta->next = Tb->next->next;
delete Tb->next; //free(Tb->next);
Tb->next = p;
return Tb;
}
2. 双向链表
2.1 基本概念与函数定义
意义
为了减少找前驱的时间复杂度,发明了双向链表。
函数定义
注意:头结点的prior指针域为空
对称性
2.2 函数定义
2.2.1 插入函数
思路
代码
void DulListInsert(DulLinklist &L, int i, Elemtype e){
if (! (p = GetElem(L,i)) ) return ERROR; // 在L中查找第i个结点,赋指针p
s = new Lnode; s->data=e; //创建要插入的结点s,给data域赋值e
s->prior = p->prior;
p->prior->next = s;
s->next = p;
p->prior = s; //重新搭桥
return OK;
}
2.2.2 删除函数
思路
代码
如果需要记录被删除的data e,则在首行括号内添加Elemtype &e, 释放操作之前
void DulListDeleteElem(DulLinklist &L, int i){
if( !(p = GetElem(L,i)) ) return ERROR; //在L中查找第i个结点,赋指针p
p->prior->next = p->next;
p->next->prior = p->prior; //重新搭桥
delete p; //free(p);
return OK;
}
时间复杂度O(n),因为有GetElem查找操作
3. 单链表,循环链表,双向循环链表的时间复杂度分析
个人感受:定义时越费事,后续越简单
双向循环链表之所以时间复杂度一直是O(1),是以空间为代价,每个结点都多一个指针域