所有图片来自数据结构与算法基础(青岛大学-王卓)的PPT,顺便安利一波,老师的课讲的很好,墙裂推荐!
链表
单链表
定义:
初始化
判断链表是否为空
空链表:链表中无元素。(头指针和头结点仍在)
判断链表是否为空算法思想:判断头结点的指针域是否为空
销毁单链表
销毁:指释放链表的所有空间,包括头指针和头结点
算法思想:从头指针开始,依次释放所有结点
清空单链表
清空:指删除链表中的所有元素,使链表成为空链表。(保留头指针和头结点)
算法思想:依次释放所有的节点,并将头结点的指针域设置为空。
计算单链表的长度
算法思想:从首元结点开始,依次计数所有结点。
int ListLength_L(LinkList L){
//返回L中数据元素的个数
LinkList p;
p=L->next; //让p指向第一个结点
i=0;
while(p){
//遍历单链表,统计结点数
i++;
p=p->next;
}
return i;
}
取单链表中第i个元素的数据
算法思想:从链表的头指针出发,顺着指针域next逐个往下搜索,直到搜索到第i个结点为止。
按值查找
返回元素的地址:
返回元素的位置序号:
时间复杂度:O(n)
在第i个结点前插入值为e的新结点
算法思想:找到ai-1的存储位置p,生成一个数据与为e的新结点s,将ai-1的next指向s,s的next指向ai。
插入本身的时间复杂度:O(1)
删除第i个结点
算法思想:找到ai-1的存储位置p,保存要删除的ai的值,让ai-1的next指向ai+1。
删除本身的时间复杂度:O(1)
单链表的建立
头插法
算法思想:从一个空表开始,每次生成一个新结点,将读入的数据放到新结点的数据域,新结点的next指向上一结点,头结点的next指向新结点。
时间复杂度:O(n)
尾插法
算法思想:从一个空表L开始,将新结点逐个插入到链表的尾部,尾指针r指向链表的尾结点。
时间复杂度:O(n)
循环链表
循环链表使一种头尾相接的链表。(即表中最后一个结点的指针域指向头结点,整个链表形成一个环)
优点:从表中任一结点出发均可以找到表中的其他结点。
带尾指针循环链表的合并
算法思想:将链表a的尾指针指向的结点的next指向链表b的头结点的next(即首元结点),将链表b的尾指针指向的结点的next指向链表a的头结点。
时间复杂度:O(1)
双向链表
定义:
双链表的结点结构:
双向循环链表
双向链表的插入
示意图:
伪代码:
双向链表的删除
示意图:
伪代码: