链表
1.相关概念:
链表结构: 物理存储结构上不连续,逻辑上连续;大小不固定
概念:
链式存储结构是基于指针实现的。我们把一个数据元素和一个指针称为结点。
数据域:存数数据元素信息的域。
指针域:存储直接后继位置的域。
链式存储结构是用指针把相互直接关联的结点(即直接前驱结点或直接后继结点)链接起来。链式存储结构的线性表称为链表。
2. 链表的四种功能
1. 访问(Access):O(N)
要一个一个访问,知道第一个然后通过next指针往下去找
最差是一个一个next找到最后
2. 搜索(Search):O(N)
和访问差不多
从头到尾遍历
最差为遍历到最后找到想找的元素
3. 插入(Insert): O(1)
插入节点和前后节点连接起来
4. 删除(Delete):O(1)
前一个节点指针指向下一个节点
3. 特点:
读 ×
写 √
写快,读慢
4.常用操作
1. 创建链表
2. 添加元素
插入元素时,
插入这一动作时间复杂度是O(1),
但是选定一个位置然后插入,时间复杂度是O(N),因为还有遍历的步骤在
3. 访问元素
get()
4.搜索元素
indexOf()
5.更新元素
set()
6.删除元素
remove()
7.链表长度
size()
复杂度是O(1),因为创建链表时,内部有个变量会帮助做长度的计算
5.Leetcode
刷题总结:
链表最后返回的都是头节点
203.移除链表元素
package qi.linkedlist;
public class RemoveList {
public ListNode removeElements(ListNode head, int val) {
ListNode dummy = new ListNode(0);
ListNode prev = dummy;
dummy.next = head;
// 判断是否为null
//当前节点是 dummy ,head刚开始是当前节点dummy的下一个节点
while (head != null ) {
// 如果当前结点的后继结点的值与给定值val相等
// 则需将其后继结点删除
if (head.val == val) {
// 通过将当前结点后继结点的后继结点挂在当前结点之后
// 来删除当前结点的后继结点
prev.next = head.next;
} else {
// 如果当前结点的后继结点的值与给定值不相等
// 则当前结点需要保留,因此prev向前移动一个位置
prev = head;
}
head = head.next;
}
return dummy.next;
}
}
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
206.反转链表
方法一:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode dummy = new ListNode(0);
dummy.next = head;
while (head != null && head.next != null) {
ListNode hN=head.next;
ListNode dN=dummy.next;
dummy.next = hN;
head.next = hN.next;
hN.next = dN;
}
return dummy.next;
}
}
方法二:(推荐)
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
while (cur != null) {
ListNode nextNode = cur.next;
cur.next = pre;
pre = cur;
cur = nextNode;
}
return pre;
}
}