手动基本实现Linkedlist集合(二)

上一篇文章讲了Linkedlist的add(),get(),toString,没有看的朋友可以去看一下:手动基本实现Linkedlist集合(一)开始后面的实现

1.添加remove(int index),移除节点方法

  1. 解释:就是讲一个节点从链表中删除

  2. 实现:改变要删除节点的前后节点指向问题

  3. 原链表格式在这里插入图片描述

  4. 删除进行的操作在这里插入图片描述

  5. 简单陈述:让它前面的next,指向它的后面;让它后面的previous,指向它的前面

  6. 注意点:当删除第一个,或最后一个时,注意改变first,或last

  7. 当删除第一个,或最后一个时,注意他们没有前一个节点,或后一个节点,指向的是null

//    因为删除   也需要遍历,将查找里的遍历与,判断索引有效都分离出来
    public void remove(int index){
        canIndex(index);
        Node node = getNode(index);
//        前一个节点
        Node up = node.previous;
//        后一个节点
        Node down = node.next;
//        防止是第一个
        if (up != null){
//    当是最后一个时候,这时倒数第二个变为最后一个,往后应该指向(最后一个的下一个--null)
            up.next = down;
        }
//        防止是最后一个
        if (down != null){
//   当是第一个时候,这时第二个应该变为第一个,往前指向(第一个的上一个--null)
            down.previous = up;
        }
//        删除第一个,改变first
        if (index == 0){
            firsrt = down;
        }
//        删除最后一个,改变last,同时 size减一
        if (index == --size){
            last = up;
        }
    }

2.优化前一篇的部分代码

//        索引有效性
    public void canIndex(int index){
        if (index <0 || index >= size){
            throw new RuntimeException("索引不合法:"+index);
        }
    }
//    只查找
    public Node getNode(int index){
        Node node ;
//        遍历查找
        if (index <= (size>>2)){
            node = firsrt;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        }else {
            node = last;
            for (int i = size-1; i > index; i--) {
                node = node.previous;
            }
        }
        return node;
    }
//    根据下标找到对象
   public Object get(int index){
        canIndex(index);
        Node node = getNode(index);
        return node.element;
    }

3.添加 add(int index,object obj),插入方法

  1. 将一个节点插入节点内部,改变两条指向,新加两条指向
  2. 插入节点示意图:
    在这里插入图片描述
  3. 上面这是中间插入示意图,但是应该注意插入到第一个位置 的不同:
    在这里插入图片描述
  public void add(int index,Object object){
        Node newnode = new Node(object);  // 新元素
        canIndex(index);  // 索引有效
        Node indexNode = getNode(index);//根据下标找出这个被挤走元素
        Object element = indexNode.element;
//        不插在第一个位置
        if (index != 0){
           Node up = indexNode.previous;

           up.next = newnode;  // 1
           newnode.previous = up;  // 2

           indexNode.previous = newnode;  // 3
           newnode.next = indexNode;  // 4
        }else {
//          插在第一个位置
            newnode.next = indexNode;
            indexNode.previous = newnode;
//            改变first
            firsrt = newnode;
        }
//        改变个数
        size++;
    }
  1. 应该用插入中间,插入第一个,插入最后一个作为检验机制
  public static void main(String[] args) {
//        LinkedList
        Linklist04 link = new Linklist04();
        link.add("ll");
        link.add("kk");
        link.add("hh");
        link.add("gg");
        link.add("ff");
//        应该用插入中间,插入第一个,插入最后一个作为检验机制
        System.out.println(link);
        link.add(4,"4");
        System.out.println(link);
        link.add(3,"3");
        System.out.println(link);
        link.add(0,"1");
        System.out.println(link);
    }

4.增加泛型,优化代码,封装部分代码,完整代码:

public class Node {
    Node previous; //上一个节点
    Node next;   // 下一个节点
    Object element;  //本节点里的元素
    public Node(Node previous, Node next, Object element) {
        super();
        this.previous = previous;
        this.next = next;
        this.element = element;
    }
    public Node(Object element) {
        super();
        this.element = element;
    }
}
public class Linklist05<E> {
    private Node firsrt;  // 第一个节点
    private Node last;    // 最后一个节点
    private int size;  //元素个数
    public Linklist05() {
        super();
    }
    public void add(int index,E elenent){
        Node newnode = new Node(elenent);  // 新元素
        canIndex(index);
        Node indexNode = getNode(index);//根据下标找出这个被挤走元素
        Object element = indexNode.element;
//        不插在第一个位置
        if (index != 0){
           Node up = indexNode.previous;
           up.next = newnode;
           newnode.previous = up;
           indexNode.previous = newnode;
           newnode.next = indexNode;
        }else {
//          插在第一个位置
            newnode.next = indexNode;
            indexNode.previous = newnode;
//            改变first
            firsrt = newnode;
        }
//        改变个数
        size++;
    }
//    因为删除   也需要遍历,将查找里的遍历与,判断索引有效都分离出来
    public void remove(int index){
        canIndex(index);
        Node node = getNode(index);
//        前一个节点
        Node up = node.previous;
//        后一个节点
        Node down = node.next;
//        防止是第一个
        if (up != null){
//            当是最后一个时候,这时倒数第二个变为最后一个,往后应该指向(最后一个的下一个--null)
            up.next = down;
        }
//        防止是最后一个
        if (down != null){
//            当是第一个时候,这时第二个应该变为第一个,往前指向(第一个的上一个--null)
            down.previous = up;
        }
//        删除第一个,改变first
        if (index == 0){
            firsrt = down;
        }
//        删除最后一个,改变last,并且 size减一
        if (index == --size){
            last = up;
        }
    }
//   改进查找,当在前一半里时,从first处开始遍历
//     反之,从 last处 从后往前遍历
    public E get(int index){
        canIndex(index);
        Node node = getNode(index);
        return (E)node.element;
    }
//    只查找
    private Node getNode(int index){
        Node node ;
//        遍历查找
        if (index <= (size>>2)){
            node = firsrt;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        }else {
            node = last;
            for (int i = size-1; i > index; i--) {
                node = node.previous;
            }
        }
        return node;
    }
//        索引有效性
    private void canIndex(int index){
        if (index <0 || index >= size){
            throw new RuntimeException("索引不合法:"+index);
        }
    }
    //	现在不考虑链表循环
    public void add(E element) {
        Node node = new Node(element);
//		第一次添加元素
        if (null == firsrt) {
            firsrt = node;
            last = firsrt;
        }else {
//			将新节点 上一个指向 之前的last
            node.previous = last;
//			last的下一个指向新对象
            last.next = node;
//			改变 last
            last = node;
        }
        size++;
    }
//   重写toString
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer("[");
        Node temp = firsrt;
        while (temp.next != null) {
            sb.append(temp.element+",");
            temp = temp.next;
        }
            sb.append(temp.element+"]");
        return  sb.toString();
    }
}

总结:

  1. 实现linkedlist集合,是根据双向链表实现,实现步骤:
  2. 节点类
  3. 集合的构造方法
  4. add(E element), 添加元素方法
  5. toString(), 打印集合方法
  6. get(int index), 获取元素方法
  7. remove(int index),移除元素
  8. add(int index,E elenent), 插入元素方法
  9. 对于 添加元素,注意: 头节点与尾节点的变化,size++
  10. 对于 移除元素,注意: 头节点与尾节点的变化,size–
  11. 对于 与位置相关的方法,第一步应该判断索引位置是否合法

结尾:有兴趣的朋友可以去看一下我的另一篇:手动基本实现Arraylist集合👀

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值