【数据结构】模拟实现LinkedList

简介: 【数据结构】模拟实现LinkedList

LinkedList是双向链表结构可以适用于任意插入场景下的插入和删除,效率较高,时间复杂度为O(1)。

模拟实现

public class MyLinkedList {
    static class ListNode{
        private int val;//值域
        private ListNode prev;//前驱
        private ListNode next;//后继
        public ListNode(int val) {
            this.val = val;
        }
    }
    public ListNode head;//双向链表的头节点
    public ListNode last;//双向链表的尾节点
}

LinkedList常用方法

//头插法
public void addFirst(int data)
//尾插法
public void addLast(int data)
//任意位置插入,第一个数据节点为0号下标
public void addIndex(int index,int data)
//查找是否包含关键字key是否在单链表当中
public boolean contains(int key)
//删除第一次出现关键字为key的节点
public void remove(int key)
//删除所有值为key的节点
public void removeAllKey(int key)
//得到链表的长度
public int size()
//清空链表
public void clear()

实现addFirst方法(头插法)

public void addFirst(int data){
  ListNode node = new ListNode(data);
    //如果链表为空 插入的元素就是头节点和尾节点
  if (head==null){
    head = node;
    last = node;
  }else {
    node.next = head;//使node的后继是现在的头节点
    head.prev = node;//使现在的头节点的前驱是node
    head = node;//让node成为新的头节点
  }
}

实现addList方法(尾插法)

public void addLast(int data){
  ListNode node = new ListNode(data);
    //和头插一样
  if (last==null){
    head = node;
    last = node;
  }else {
    last.next = node;//使现在尾节点的后继为node
    node.prev = last;//使node的前驱为现在的尾节点
    last = last.next;//让node成为尾节点
  }
}

实现size方法(求链表长度)

public int size(){
  ListNode cur = head;
  int count = 0;
  while (cur!=null){
    count++;
    cur = cur.next;
  }
  return count;
}

实现addIndex方法(在任意位置插入元素)

public void addIndex(int index,int data){
    //插入的位置如果为0 可以使用头插法
  if (index==0){
    addFirst(data);
    return;
  }
    //如果在最后一个位置插入 可以使用尾插法
  if (index==size()){
    addLast(data);
    return;
  }
  ListNode node = new ListNode(data);
    //判断要插入的下标是否合法
  if (index<0||index>size()){
    System.out.println("index 不合法"+index);
    return;
  }
  ListNode cur = head;
    //让cur走到要插入的位置
  while (index!=0){
    cur = cur.next;
    index--;
  }
  node.next = cur;
  cur.prev.next = node;
  node.prev = cur.prev;
  cur.prev = node;
}

实现contains方法(查找是否包含关键字key是否在单链表当中)

public boolean contains(int key){
  if (head==null){
    return false;
  }
  ListNode cur = head;
  while (cur!=null){
    if (cur.val==key){
      return true;
    }
    cur = cur.next;
  }
  return false;
}

实现remove方法(删除第一次出现关键字为key的节点)

public void remove(int key){
    ListNode cur = head;
    while (cur!=null){
        if (cur.val==key){
            //删除头节点
            if (cur==head){
                head = head.next;
                if (head==null){
                    //只有一个头节点
                    cur.prev=null;
                }else {
                    last=null;
                }
                }else {
                    if (cur.next!=null){
                        //删除中间节点
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                    }else {
                    //删除尾节点
                    cur.prev.next=cur.next;
                    last=last.prev;
                }
            }
            return;
        }else {
            cur=cur.next;
        }
    }
}

实现removeAllkey(删除所有值为key的节点)

public void removeAllKey(int key){
    ListNode cur = head;
    while (cur!=null){
        if (cur.val==key){
            //删除头节点
            if (cur==head){
                head = head.next;
                if (head==null){
                    //只有一个头节点
                    cur.prev=null;
                }else {
                    last=null;
                }
                }else {
                    if (cur.next!=null){
                        //删除中间节点
                        cur.prev.next=cur.next;
                        cur.next.prev=cur.prev;
                  }else {
                      //删除尾节点
                      cur.prev.next=cur.next;
                      last=last.prev;
                }
            }
            cur=cur.next;
        }else {
            cur=cur.next;
        }
    }
}

实现clear方法(清除链表)

public void clear(){
    ListNode cur = head;
    while (cur!=null){
        ListNode curNew = cur.next;
        cur.prev=null;
        cur.next=null;
        cur = curNew;
    }
    head=null;
    last=null;
}
相关文章
|
1月前
|
存储 Java 索引
Java中的数据结构:ArrayList和LinkedList的比较
【10月更文挑战第28天】在Java编程世界中,数据结构是构建复杂程序的基石。本文将深入探讨两种常用的数据结构:ArrayList和LinkedList,通过直观的比喻和实例分析,揭示它们各自的优势与局限,帮助你在面对不同的编程挑战时做出明智的选择。
|
2月前
|
Java C++ 索引
让星星⭐月亮告诉你,LinkedList和ArrayList底层数据结构及方法源码说明
`LinkedList` 和 `ArrayList` 是 Java 中两种常见的列表实现。`LinkedList` 基于双向链表,适合频繁的插入和删除操作,但按索引访问元素效率较低。`ArrayList` 基于动态数组,支持快速随机访问,但在中间位置插入或删除元素时性能较差。两者均实现了 `List` 接口,`LinkedList` 还额外实现了 `Deque` 接口,提供了更多队列操作。
28 3
|
2月前
|
存储 缓存 索引
从底层数据结构和CPU缓存两方面剖析LinkedList的查询效率为什么比ArrayList低
本文详细对比了ArrayList和LinkedList的查询效率,从底层数据结构和CPU缓存两个方面进行分析。ArrayList基于动态数组,支持随机访问,查询时间复杂度为O(1),且CPU缓存对其友好;而LinkedList基于双向链表,需要逐个节点遍历,查询时间复杂度为O(n),且CPU缓存对其帮助不大。文章还探讨了CPU缓存对数组增删操作的影响,指出缓存主要作用于读取而非修改。通过这些分析,加深了对这两种数据结构的理解。
47 2
|
6月前
|
存储 Java 索引
【Java】LinkedList vs. ArrayList:Java中的数据结构选择
【Java】LinkedList vs. ArrayList:Java中的数据结构选择
32 3
|
7月前
|
算法 测试技术
【数据结构与算法 | 基础篇】模拟LinkedList实现的双向循环链表
【数据结构与算法 | 基础篇】模拟LinkedList实现的双向循环链表
|
7月前
|
存储 算法 Java
【数据结构与算法 | 基础篇】模拟LinkedList实现的双向链表
【数据结构与算法 | 基础篇】模拟LinkedList实现的双向链表
|
7月前
|
算法
【数据结构与算法 | 基础篇】模拟LinkedList实现的链表(无哨兵)
【数据结构与算法 | 基础篇】模拟LinkedList实现的链表(无哨兵)
|
存储 JavaScript 前端开发
数据结构之LinkedList | 让我们一块来学习数据结构
数据结构之LinkedList | 让我们一块来学习数据结构
45 0
|
存储 Java
Java数据结构之第五章、LinkedList与链表
由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比较低,因此ArrayList不适合做任意位置插入和删除比较多的场景。
64 0
|
存储 Java 开发者
Java-数据结构(三)-List:ArrayList和LinkedList及其相关面试题
Java-数据结构(三)-List:ArrayList和LinkedList及其相关面试题
230 0