1、单链表建立
1)头插法:可以用于将已存在链表逆序
2)尾插法:
2、顺序表与单链表比较
1)存取方式
顺序表存取方便,支持随机存取,单链表只能从表头顺序存取
2)查找、插入和删除
按值查找:当顺序表无序时,两者时间复杂度均为O(n); 当顺序表有序时,可以用折半查找,时间复杂度为O(log2n)
按序号查找:顺序表时间复杂度为O(1),单链表时间复杂度为O(n)
插入和删除:顺序表时间复杂度为O(n),单链表时间复杂度为O(1)
3)空间分配
单链表存储的节点空间在需要的时候申请分配,操作灵活、高效
3、快慢指针及其应用
1)判断单链表是否存在环
快慢指针同时从头结点开始移动,利用快指针每次移动两个位置,慢指针每次移动一个位置,如果快指针到达NULL,说明无环,否则有环。
有一个扩展:如何寻找循环链表入口?
快慢指针同时从头结点移动,第一次相遇后,再让慢指针从头结点开始移动,并且此时快慢指针移动的步数一致,则第二次相遇即为循环链表入口。
2)在有序链表中寻找中位数
快慢指针同时从头结点移动,快指针移动两个位置,慢指针移动一个位置,当快指针移动到NULL时,慢指针位置即为中位数位置,在这过程中要注意链表结点个数的奇偶影响。
3)寻找链表倒数第k个结点
定义两个指针从头结点移动,先第一个指针移动k-1步,再两个指针同时移动,当第一个指针到达尾节点时,第二个指针位置正好是倒数第K个结点。
4)两个单链表判断是否相交,并找出相交的第一个公共结点
首先利用快慢指针判断是否存在环,再分类去做
a、如果都不存在环
如何判断是否相交:
只要分别遍历两个链表到尾节点,并判断尾节点是否相同,相同则相交,否则不相交
如何找出相交的第一个公共结点:两种方法
方法一:遍历a链表,每次遍历其中一个结点的时候,在b链表中顺序遍历每个结点,若在顺序遍历b链表的过程中,发现两个链表的结点是一样的,则第一个公共结点为此时遍历的a或b链表中的结点,时间复杂度为O(mn),m、n分别为链表a和链表b的长度
方法二:设链表a的长度为La,链表b的长度为Lb,假定链表a比链表b更长,则先在链表a上遍历La-Lb个结点,然后链表a和链表b同时遍历,则第一个相同的结点就是第一个公共结点,此时时间复杂度为O(m+n)
b、一个存在环,一个不存在环
这种情况肯定不想交
c、两个都存在环
当确定存在环时,则判断任意一个链表上环入口处的那个结点在不在另一条链表上,若在,则相交,否则不相交。并且任意一个链表上环入口处的那个结点都可以定义为两条链表相交的第一个结点