链表
什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
链表的入口节点称为链表的头结点也就是head。
链表的类型
单链表
刚刚说的就是单链表。
双链表
单链表中的指针域只能指向节点的下一个节点。
双链表:每一个节点有两个指针域,一个指向下一个节点,一个指向上一个节点。
双链表 既可以向前查询也可以向后查询。
循环链表
循环链表,顾名思义,就是链表首尾相连。
循环链表可以用来解决约瑟夫环问题。
链表的存储方式
了解完链表的类型,再来说一说链表在内存中的存储方式。
数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。
链表是通过指针域的指针链接在内存中各个节点。
所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。
Java实现链表:
public class ListNode {
// 结点的值
int val;
// 下一个结点
ListNode next;
// 节点的构造函数(无参)
public ListNode() {
}
// 节点的构造函数(有一个参数)
public ListNode(int val) {
this.val = val;
}
// 节点的构造函数(有两个参数)
public ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
移除链表元素
直接使用原链表删除元素:
//不用if,因为移除头节点是一个持续的过程,如果链表是1->1->1,目标为1用if就错了。
while(head != null && head.val == target){
head = head.next;
//如果是c++需要进行头节点的释放,其他语言有垃圾回收机制
}
cur = head;
while(cur != null && cur.next != null){
if(cur->next->val == target){
cur->next = cur->next->next;
}else{
cur = cur->next;
}
}
return head;
使用虚拟头节点(在非头节点和头节点操作时统一了操作):
dummyhead = new ListNode;
dummyhead.next = head;
cur = dummyhead;//实际删除的是cur的next
while(cur.next != null){
if(cur.next.val == target){
cur.next = cur.next.next;
}else{
cur = cur.next;
}
}
return dummyhead.next;
题目代码:
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode(-1, head);
//ListNode pre = dummyNode;
ListNode cur = dummyNode;
while(cur.next != null){
if(cur.next.val == val){
cur.next = cur.next.next;
}else{
cur = cur.next;
}
//cur = cur.next;
}
return dummyNode.next;
}
}
cur = cur.next;
}
//cur = cur.next;
}
return dummyNode.next;
}
}
设计链表
获取第n个节点的值(n从0开始):
cur = dummyhead.next;
while(n ){
cur = cur.next;
n--;
}
return cur.val;
头部插入节点:
newnode = new node();
newnode.next = dummyhead.next;
dummynode.next = newnode;
size++;
尾部插入节点:
cur = dummyhead;
while(cur.next != null){
cur = cur.next;
}
cur.next = newnode;
size++;
第n个节点前插入:
cur = dummyhead;
while(n--){
cur = cur.next;
}
newnode.next = cur.next;
cur.next = newnode;
size++;
删除第n个节点:
cur = dummyhead;
while(n){
cur = cur.next;
n--;
}
cur.next = cur.next.next;
size--;