Java基础知识总结(54)

(1) 手动实现LinkedList

LinkedList底层结构实现和ArrayList底层数据结构实现有着本质上的区别
ArrayList底层实现主要依赖数组,而LinkedList底层实现则是依赖链表。

/**

  • LinkedList的实现是双向链表,因此需要定义首节点和尾结点。

  • 并且需要保存链表中元素的个数。此外,还需要提供无参构造方法,

  • 在构造方法内初始化一个空链表。 */ public class MyLinkedList { private Node first; private Node last; private int size;

    /**

    • 在尾部添加节点

    • @param o

    • @return */ public boolean add(Object o){ if(size == 0){ Node newNode = new Node(null,o,null); first = newNode; last = newNode; }else{ //实例化新节点 Node newNode = new Node(last,o,null); last.next = newNode; last = newNode; } size++; return true; }

/**
 * 在指定索引处添加节点
 * @param index
 * @param o
 * @return
 */
public boolean add(int index,Object o){
    if(index<0 || index>size){
        throw new IndexOutOfBoundsException("越界!");
    }
    if(index == 0){
        //获取指定索引处的节点
        Node newNode = getNode(index);
        //获取首节点的前置节点
        Node pre = first.pre;
        //首节点的前置节点指向新节点
        pre.next = newNode;
        //将新节点作为首节点
        first = newNode;
        size++;
    }
    if(index == size){
        //直接将对象添加到尾部
        add(o);
    }
    //获取索引的节点
    Node indexNode = getNode(index);
    //获取索引节点的前置节点
    Node preNode = indexNode.pre;
    //实例化新节点 per指向索引节点的前置节点,next指向索引节点的后置节点
    Node newNode = new Node(preNode,o,indexNode);
    //索引节点前置节点的next指向新节点
    preNode.next = newNode;
    //索引节点的pre指向新节点
    indexNode.pre = newNode;
    size++;
    return true;
}
​
/**
 * 删除对应索引处的节点
 * @param index
 * @return
 */
public Object remove(int index){
    if(index<0 || index>=size){
        throw new IndexOutOfBoundsException("越界");
    }
    //初始化返回的值
    Object o = null;
    //删除首节点
    if(index ==0) {
        //获取首节点的节点值
        o = first.date;
        //获取首节点的后置节点
        Node node = first.next;
        //首节点的next为null
        first.next = null;
        //将首节点的后置节点作为首节点
        first = node;
    }
    //删除尾节点
    else if(index == size-1){
        o = last.date;
        //获取尾节点的前置节点
        Node perNode = last.pre;
        //尾节点的前置节点的next置为null
        perNode.next = null;
        //将索引节点的尾节点作为尾节点
        last = perNode;
    }else{
        //删除中间节点
        //获取索引处节点
        Node indexNode = getNode(index);
        o = indexNode.date;
        //获取索引节点的前置节点
        Node preNode = indexNode.pre;
        //获取索引节点的后置节点
        Node nextNode = indexNode.next;
        //将索引节点的前置节点指向索引节点的后置节点
        preNode.next = nextNode;
        //将索引节点的后置节点指向索引节点的前置节点
        nextNode.pre = preNode;
        //将索引节点的pre置为null
        indexNode.pre = null;
        //将索引节点的next置为null
        indexNode.next = null;
    }
    size--;
    return o;
}
​
/**
 * 修改索引处节点的元素值
 * @param index
 * @param o
 * @return
 */
public Object set(int index,Object o){
    if(index<0||index>=size){
        throw new IndexOutOfBoundsException("越界!");
    }
    //获取对应索引处的节点
    Node indexNode = getNode(index);
    //获取要删除节点的值
    Object oldValue = indexNode.date;
    //将要修改的值赋值给目标节点
    indexNode.date = o;
    return oldValue;
}
​
/**
 * 获取双向链表的容量
 * @return
 */
public int size(){
    return size;
}
​
/**
 * 获取对应索引处节点的元素值
 * @param index
 * @return
 */
public Object get(int index){
    return getNode(index).date;
}
​
/**
 * 获取对应索引处的Node对象
 * @param index
 * @return
 */
public Node getNode(int index){
    if(index<0 || index>=size){
        throw new  IndexOutOfBoundsException("越界");
    }
    //获取首节点
    Node current = first;
    for (int i = 0; i < index&&current!=null; i++) {
        //获取下一个节点
        current = current.next;
    }
    return current;
}
​
/**
 * 定义链表数据节点
 */
private class Node{
    private Node pre;
    private Object date;
    private Node next;
​
    public Node(Node pre,Object o,Node next){
        this.pre = pre;
        this.date = o;
        this.next = next;
    }
}

}

/**

  • 测试类 */ public class Test { public static void main(String[] args) { MyLinkedList list = new MyLinkedList(); list.add("111"); list.add("222"); list.add("333"); list.add("444"); list.set(1,"777"); list.set(2,"888"); list.remove(0); list.remove(1); System.out.println("-------------"); for (int i = 0; i <list.size(); i++) { System.out.println(list.get(i)); } } }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好教员好

您的鼓励是我前进动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值