数据结构与算法—链表
声明:以下都是学的尚硅谷网课所记的笔记。
单链表
单链表:是有序的列表,但在内存中的存储不是连续的。
特点:
- 链表以节点方式存储;
- 每个节点有data域,next域,分别存放数据和下一个节点地址;
- 各节点在内存中不一定连续存放;
- 链表分为带头节点和不带头节点的链表。
单链表的结构图如下:
每一个节点都是自己编写的类对象,类中包含数据和下一个节点信息(即地址)。
往链表的指定位置插入节点
- 首先找到新添加节点的位置(通过辅助变量指针temp,遍历搞定),通过
temp = temp.next
往后移动;temp为添加位置的前一个位置,否则加不进去。 新节点.next = temp.next
;temp.next = 新的节点
。
面试题
新浪面试题:查找单链表的倒数第k个节点
思路:
- 编写一个方法,接受一个head节点,同时接受一个k表示倒数第几个节点;
- 先把链表从头到尾遍历,得到链表的长度size,注意判断size和k的关系,如果k>size显然不满足,直接返回。
- 得到size后,从链表第一个开始遍历 size-k 个节点,就可以得到倒数第k个节点。
腾讯面试题:单链表反转
思路:
- 先定义一个节点(头),
reverseHead = new Node()
; - 定义一个指针(curretNode)指向当前节点,从头到尾遍历原来的链表,每遍历一个节点将其取出,放在新链表的最前端;
currentNode.next = reverseNode.next;
reverseNode.next = currentNode;
- 最后
head.next = reverseHead.next
,将原来的链表头指向新链表头,完成反转。
百度面试题:从尾到头打印单链表
思路:
- 方法1:先将链表反转,然后再遍历,但会破坏原来链表结构;
- 方法2:利用栈这个数据结构(后入先出),先遍历将各个节点压入栈中,然后由栈的特点,就实现了逆序打印。
双链表
特点
- 有一个pre指针和next指针,分别指向前一个节点和后一个节点,也有一个data域存放数据;
- 可以向前或向后查找;
- 可以自我删除,不需要靠辅助节点。
双链表结构图:
分析:
- 遍历方式和单链表一样,可以向前也可以向后查找;
- 添加节点(newNoed)到末尾时 -> 先找到啊末尾节点temp ->
temp.next = newNode
->newNode.pre = temp
; - 修改思路和原来一样,只需要找到节点然后修改属性;
- 删除:直接找到待删除的节点,比如temp ->
temp.pre.next = temp.next
->temp.next.pre = temp.pre
。
单向环形链表(无头节点)
单向环形列表构建思路:
- 先创建一个节点,让该节点的next指向first指针(first总是指向第一个节点),形成环形;
- 后面每当我们创建一个新的节点newNode,就把该节点放到已有的环形链表最后一个节点current的后面(current指针指向当前的尾部节点),然后让
newNode.next = first
构成环形, 然后将current再指向当前节点即最后一个节点。
循环链表遍历:因为first总是指向第一个节点,可以先让一个辅助指针(current)指向first节点,通过while循环遍历该环形链表即可。当 current.next == first
表示遍历结束。
---------------------------- 个人学习笔记----------------------------