Java 链表学习
Linked List
- 单链表
- 双链表
- 循环链表
基本定义
链表是一种数据结构,和数组同级。比如,Java中我们使用的ArrayList,其实现原理是数组。而LinkedList的实现原理就是链表了。链表在进行循环遍历时效率不高,但是插入和删除时优势明显。与数组不同,我们无法在恒定时间内访问单链表中的随机元素。如果我们想得到第i个元素,就得从头节点开始一个一个地遍历。按索引访问一个元素平均需要 O(N) 时间,其中 N 是链表的长度。
链表是通过节点(Node)构成,head指针指向第一个成为表头节点(头节点不存放数据),而终止于最后一个指向Null的指针。Null表示空指针,没有指向的值。
单链表 Singly Linked List
单链表由像链一样链接在一起的节点组成。现在要访问这个链,我们需要一个指针来跟踪列表的第一个元素。只要我们有关于第一个元素的信息,我们就可以遍历列表的其余部分,而不必担心记住它们的存储位置。单链表包含一个头节点:指向列表第一个元素的指针。每当我们想要遍历列表时,我们都可以使用这个头节点来实现。
以下是单链表中节点的典型定义:
// Definition for singly-linked list.
public class SinglyListNode {
// Node 类将数据存储在单个节点中。它可以存储原始数据,例如整数和字符串以及具有多个属性的复杂对象
// 除了数据,它还存储指向列表中下一个元素的指针,这有助于像链一样将节点链接在一起
int val; // 节点数据
SinglyListNode next; // 指针,用来指向下一个节点(Pointer to next node in list)
//构造函数
SinglyListNode(int x) {
val = x; // 把接收的参数赋值给当前类的val变量
}
}
添加节点
如果想在链表中添加新节点,我们应该执行三个步骤:
- 用给定值初始化一个新节点 cur
- 将 cur 节点的 “next” 指针链接到 prev 的下一个节点 next
- 将 prev 中的“next”指针链接到 cur
![添加节点](https://img2022.cnblogs.com/blog/2849669/202204/2849669-20220423133849111-1808458127.png)
删除节点
如果我们想从单链表中删除一个现有的节点 cur,我们可以分两步完成:
- 查找 cur 的上一个节点 prev 及其下一个节点 next
- 将 prev 链接到 cur 的下一个节点 next
707. Design Linked List
class Node {
int val; // node
Node next; // pointer
// constructor
public Node(int val){
this.val = val;
this.next = null;
}
}
class MyLinkedList {
public Node head; // head node of the linked list
public int size; // the length of the linked least
// Construcator - initializes head node and size value
public MyLinkedList() {
size = 0;
head = new Node(0);
}
public int get(int index) {
Node curNode = head;
// the index < 0 and > the linked size are invalid, return -1
if(index < 0 || index >= size) return -1;
// if valid
for(int i = 0;i <= index; i++){
curNode = curNode.next;
}
return curNode.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
/**
Add a node of value val before the index-th node in the linked list.
If index equals to the length of linked list, the node will be appended to the end of linked list.
If index is greater than the length, the node will not be inserted.
*/
public void addAtIndex(int index, int val) {
// Create a new node with value data
Node curNode = new Node(val);
Node prevNode = head;
// If index is greater than the length
// The node will not be inserted.
if(index > size) return;
// if index is negative
// the node will be inserted at the head of the linked list
if(index < 0) index = 0;
for (int i = 0; i<index; i++){
prevNode = prevNode.next;
}
size++; // update the length of linked list
// make newNode the next element of the last node
// Link the "next" field in prev to cur.
curNode.next = prevNode.next;
prevNode.next = curNode;
}
/**
Delete the index-th node in the linked list, if the index is valid.
*/
public void deleteAtIndex(int index) {
// if index is invalid, do nothing
if(index < 0 || index >= size) return;
Node prevNode = head; // head node
// Traverse the linked list from the head until we find the previous node prev
for(int i = 0; i<index; i++){
prevNode = prevNode.next;
}
size--; // update length
// Link prev to cur's next node next, which is prev's next of next
prevNode.next = prevNode.next.next;
}
}
本文作者:Kane,转载请注明原文链接:https://www.cnblogs.com/hackerk/p/16492639.html