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

说明Linkedlist

1.Linkedlist时基于链表实现的,如图所示
在这里插入图片描述
2.源码里它用一个类Node来代替一个节点:

 private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

现在开始实现(先不添加泛型,最后改进)

1.实现节点类

一般用第二个构造方法,先实现类,再实现细节

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;
    }
}

2.实现add(),toString()

现在实现的链表结构并不是第一张图片的样子(一个循环双向链表),
现在的链表结构如下图所示,是一个首尾不相连,都指向空的逻辑,注意比较
在这里插入图片描述

public class Linklist01 {
    private Node firsrt;  // 第一个节点
    private Node last;    // 最后一个节点
    private int size;  //元素个数
    public Linklist01() {
        super();
    }
    //	现在不考虑链表循环
    public void add(Object object) {
        Node node = new Node(object);
//		第一次添加元素
        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();
    }
}

用添加元素"ll",“kk”,“hh”,与打印验证代码

    public static void main(String[] args) {
        Linklist01 link = new Linklist01();
        link.add("ll");
        link.add("kk");
        link.add("hh");
        System.out.println(link);
    }

通过工具查看具体逻辑结构,如下图

在这里插入图片描述
-----------------------------------------------------------------------------------------------------
在这里插入图片描述
-----------------------------------------------------------------------------------------------------
在这里插入图片描述
最后一张图片可能比较乱,但是说明了内部的指向问题:
在这里插入图片描述

3.添加get(),遍历节点代码

 public Object get(int index){
//        索引有效性
        if (index <0 || index >= size){
            throw new RuntimeException("索引不合法:"+index);
        }
        Node node = firsrt;
//        遍历查找
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node.element;
    }

但是上面的代码效率低,如下情况:集合长度600,查询下标599的元素,要把集合全部遍历一遍,效率差。
所以应该采用,下标在前一半里,从前往后;在后一半里,从后往前,
下面是改进代码:

//   改进查找,当在前一半里时,从first处开始遍历
//     反之,从 last处 从后往前遍历
    public Object get(int index){
//        索引有效性
        if (index <0 || index >= size){
            throw new RuntimeException("索引不合法:"+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.element;
    }

4.下一篇文章继续,😁,下一篇连接手动基本实现Linkedlist集合(二)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值