前言
链表的结构简单,它由指针把若干个节点连接成链状结构。那么必然涉及到链表的创建,如何插入节点,如何删除节点等链表操作。由于这些操作思想简单,还可借助画图理解实现,代码量又不多,因而在面试中经常出现。
链表是一种动态的数据结构,在创建链表的时候,我们无需提前知道链表的长度,而是按需为新节点分配内存即可,这样一来空间的利用率就比数组相对高了。
链表的部分操作
链表节点定义
链表尾部加入节点
在上面代码中,函数的第一个参数 head 是一个指向指针的指针(二级指针)。由于此时会改动头指针(形参),而我们也需要改变头指针对应的实参,那么需要使用二级指针传递,即需要再加一级的指针,这样当对形参(指向头指针的指针)的指向操作时,就相当于对实参(头指针)本身进行的操作。
链表删除节点
题目描述(从尾到头打印链表)
题目:输入一个链表的头结点,从尾到头反过来打印出每个节点的值(不改变链表结构)。
解题思路一
利用栈线性处理。当我们遍历链表的时候是从头开始访问元素,而输出的时候确要从后面访问的元素先输出,由此联想到栈的特性—后进先出。那么一旦我们访问一个节点就将其入栈,遍历结束后再统一出栈即可逆序输出链表节点。
解题思路二
利用递归的思想。我们每访问一个节点的时候,先递归输出它后面的节点,再输出该节点本身,这样链表的输出结果就反过来了。但是,一旦链表过长,会导致递归层级过深。
算法实现
算法实现一
算法实现二
复杂度分析
解题思路一中,对链表和栈分别仅遍历一次,时间复杂度为 O(n),由于借助了栈,其递归深度为O(n),因而空间复杂度为 O(n);
解题思路二同上(递归本质上一个栈的结构)。
参考
<<剑指offer2>>