目录
链表的定义
链表通过指针将一组零散的内存块串联在一起。其中,我们把内存块称为链表的“结点”。为了将所有的结点串起来,每个链表的结点除了存储数据之外,还需要记录链上的下一个结点的地址。
链表的特点
- 不需要连续的内存空间
- 有指针引用
三种最常见的链表结构
最常见的链表结构有单链表、双向链表和循环链表,我们这里只介绍单向链表。
单链表
数据结构逻辑图
单向链表(单链表)是链表的一种,其特点是链表的连接方向是单向的,对链表的访问要从头部开始顺序读取。
定义链表节点
逻辑梳理
结点除了在·下一个结点的地址
代码实现
public class ListNode{
/**
* 值
*/
int value;
/**
* 下一个的指针
*/
ListNode next;
ListNode(int value){
this.value = value;
this.next = null;
}
}
定义链表属性值
逻辑梳理
- 我们的单向链表只需要最简单的2个元素,头和大小即可
代码实现
public class MyLinkedList {
/**
* 头
*/
private ListNode head;
/**
* 大小
*/
private int size = 0;
}
定义头部插入方法
逻辑梳理
- 初始新化节点
- 新节点的下一个节点的地址 赋值为 原本head的地址
- 新的节点成为head
代码实现
/**
* 插入头
*
* @param data 数据
*/
public void insertHead(int data){
// 初始新化节点
ListNode newNode = new ListNode(data);
// 新节点的下一个节点的地址 赋值为 原本head的地址
newNode.next = head;
// 新的节点成为head
head = newNode;
}
定义指定位置插入方法
逻辑梳理
-
获取当前指定位置的节点
-
保证不断链
(1)新加的点指向后
(2)把当前的点指向新加的点
代码实现
/**
* 插入指定位置
*
* @param data 数据
* @param position 位置
*/
public void insertNth(int data,int position){
// 这个表示插入在头部了
if(position == 0) {
insertHead(data);
}else{
ListNode cur = head;
for(int i = 1; i < position ; i++){
//一直往后遍历,是为了获取当前节点
cur = cur.next;
}
ListNode newNode = new ListNode(data);
// 以下2步,保证不断链
// 1、新加的点指向后面
newNode.next = cur.next;
// 2、把当前的点指向新加的点
cur.next = newNode;
}
}
定义删除头方法
逻辑梳理
把head的点指向head的下一个点
代码实现
/**
* 删除头
*/
public void deleteHead(){
// 把head的点指向head的下一个点
head = head.next;
}
定义指定位置删除方法
逻辑梳理
-
获取当前指定位置的节点
-
保证不断链
(1)删除的点的指向,指向在下一个点,即cur.next = cur.next.next
代码实现
/**
* 删除指定位置
*
* @param position 位置
*/
public void deleteNth(int position){//O(n)
if(position == 0) {
deleteHead();
}else{
ListNode cur = head;
for(int i = 1; i < position ; i ++){
// 一直往后遍历,是为了获取当前节点
cur = cur.next;
}
// 删除的点的指向,指向在下一个点
cur.next = cur.next.next;
}
}
定义查找方法
逻辑梳理
- 节点不为空则判断传入值与节点值是否相同,相同则退出。不相同则判断下一个节点
代码实现
/**
* 查找
*
* @param data 数据
*/
public void find(int data){
ListNode cur = head;
while(cur != null){
if(cur.value == data) {
break;
}
cur = cur.next;
}
}
/**
* 查找
*
* @param data 数据
*/
public void find(int data){
ListNode cur = head;
while(cur != null){
if(cur.value == data) {
break;
}
cur = cur.next;
}
}