文章目录
- 引言
- 链表
- 节点
- 单向链表
- 双向链表
- 链表的优缺点
- java封装的链表
- 自己实现一下链表
- LinkNode节点类
- LinkedList类实现
- 示例图
- 代码
引言
1、新建的节点需要两个值:value 和 节点 next;
2、新建的节点链表需要有一个head;
3、根据位置对链表进行添加、删除操作时需要注意判断位置;
链表
链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的引用
双向链表中还包括指向前一个节点的引用
节点
- 单向节点有两个值:
- value - 当前节点的值;
- next - 下一个节点的地址
- 双向节点有三个值:
- pre - 前一个节点的地址
- value - 当前节点的值
- next - 下一个节点的地址
单向链表
双向链表
链表的优缺点
- 优点
1、不需要初始化容量,无需在创建时确定大小
2、插入和删除的时间复杂度是O(1)
3、如果发生内存回收时,无需大量移动对象,只需改变指针即可 - 缺点:
1、访问链表中的元素需要从头开始遍历,时间复杂度为O(n)。
2、每个链表节点不仅需要存储数据,还需要存储指向前后节点的引用,因此相比数组,链表会占用更多的内存空间
java封装的链表
- java内部封装了一个LinkedList类
使用的是双向链表
- LinkedList集合的一些方法
LinkedList<String> linkedList = new LinkedList<>();
- boolean add(Object element) 它将元素附加到列表的末尾。
Boolean b1 = linkedList.add("hello"); //将"hello"添加到链表linkedList的尾部,即尾插法
- boolean add(int index,Object element) 指定位置插入
Boolean b2 = linkedList.add(3,"java"); //将"java"添加到链表linkedList的第3个位置,即中间插入法
- void addFirst(E element) 元素附加到列表的头部
Boolean b3 = linkedList.addFirst(); //将"world"添加到链表linkedList的头部,即头插法
- void addLast(E element) 元素附加到列表的尾部
linkedList.addLast("time"); //将"world"添加到链表linkedList的尾部,即尾插法
- Object get(int index) 根据下标获取数据
String s1 = linkedList.get(3) ; //返回linkedList第三个位置的数据
- Object getFirst() 它返回链表的第一个元素。
String s2 = linkedList. getFirst(); //返回linkedList第一个位置的数据
- Object getLast() 它返回链接列表的最后一个元素
String s3 = linkedList.getLast() ; //返回linkedList最后一个元素
- boolean contains(Object element)如果元素存在于列表中,则返回true
Boolean b4 = linkedList.contains("java"); //如果“java”在linkedList中返回true,不存在返回false
- Object set(int index,Object element)它用于用新元素替换列表中的现有元素
String s3 = linkedList.set(0,"China") ; //用“china”替换linkedList第一个位置的数据
- E remove() 删除第一个元素
String s4 =linkedList.remove() ; //删除linkedList第一个位置的数据
- E remove(int location) 删除指定位置的元素
String s5 =linkedList.remove(2) ; //删除linkedList第2个位置的数据
- E removeFirst() 删除并返回链接列表的头部一个元素
String s6 =linkedList.removeFirst() ; //删除并返回linkedList第一个位置的数据
- E removeLast() 删除并返回链接列表的尾部一个元素
String s7 =linkedList.removeLast() ; //返回linkedList第一个位置的数据
- .clear():它删除列表中的所有元素。
linkedList.clear(); //删除linkedList中的所有元素
- .size() 返回链表长度
linkedList.size() ; //返回linkedList的长度
- boolean add(Object element) 它将元素附加到列表的末尾。
自己实现一下链表
以下实现是以单向链表为基准的实现
LinkNode、LinkedList类建议放在同一个包下
LinkNode节点类
public class LinkNode {
int value;
LinkNode next;
// 创建一个节点
public LinkNode(int value) {
this.value = value;
}
@Override
public String toString() {
return "LinkedNode{" + "value=" + value + ", next=" + next + '}';
}
}
LinkedList类实现
示例图
- 头插法示例图
- head为空
- head不为空
- head为空
- 尾插法示例图
- head为空:图同头插法
- head不为空
- 中间插入示例图
- 插入的位置是0,调用头插法
- 插入的位置是链表的长度,调用尾插法
- 0 < 插入的位置 < 链表的长度
- 删除某个节点示例图
- 判断位置是否合法,根据链表的长度去判断即可,这里不多说了
- 删除第一个
head = head.next;
- 删除其他位置
pre = index.next;
return
代码
public class LinkedList {
public LinkNode head;
// 获取链表的长度
public int length(){
int count = 0;
LinkNode index = head;
while (index!=null){
index = index.next;
count++;
}
return count;
}
// 头插法
public void headInsert(int value){
LinkNode node = new LinkNode(value);
if(head==null){
head = node;
return;
}
node.next = head;
head = node;
}
// 尾插法
public void rearInsert(int value){
LinkNode node = new LinkNode(value);
LinkNode index = head;
if(head==null){
head=node;
return;
}
while(index.next!=null){
index = index.next;
}
index.next = node;
}
// 中间插入
public void add(int position,int value){
LinkNode node = new LinkNode(value); // 插入的值的节点
if(position==0){
headInsert(value);
}else if(position==length()){
rearInsert(value);
}else{
LinkNode index = head; // 遍历的节点
LinkNode pre = null; // 遍历节点的前一个节点
int count = 0; // 用来记录遍历到哪个位置了
while (index!=null){
if(position==count){
pre.next = node;
node.next = index;
}
pre = index; // 将当前的节点赋给pre
index = index.next; // 遍历节点往后走
count++; // 位置增加
}
}
}
// 删除
public void delete(int position){
// 判断位置是否合法
if(position<0 || position>=length()){
System.out.println("删除位置不合法");
}
// 首位置删除
if(position==0){
head = head.next;
}else{
int count = 0;
LinkNode index = head; // 要遍历的链表的节点
LinkNode pre = null; // 用来记录的前一个节点
while (index!=null){
// 如果count正好是要删除的位置
if(count==position){
pre.next = index.next; // 删除成功,返回
return;
}
// count与要删除的位置不等
pre = index; // 记录前一个节点
index = index.next; // 记录当前节点
count++; // 数值增加
}
}
}
// 打印值
@Override
public String toString() {
String s = "";
while(head!=null){
s+=head.value+" ";
head = head.next;
}
return s;
}
}