Java手动实现单向链表

public class SinglyLinkedList<E> {
    private Node<E> first;
    private Node<E> last;

    public SinglyLinkedList(){

    }

    private int size = 0;
    private Node addFirst(Node node){
        first = node;
        return node;
    }
    private Node addLast(Node node){
        if(null == last){
            last = node;
            first.next = last;
        }else{
            Node tmp = last;
            last = node;
            tmp.next = last;
        }
        return last;
    }

    // 在链表末尾追加元素,可以看出的是,链表的添加不涉及循环,时间复杂度为O(1)
    public Node append(E e){
        Node n = new Node<>(e,null);
        // 此时是一个空list
        if(null == first) {
            size++;
            return addFirst(n);
        }else{
            size++;
            addLast(n);
        }

        return n;
    }

    // 这种方法需要遍历链表找到被删除节点的前驱节点,时间复杂度为O(n)
    public E remove(E e){
        Node n = first;
        if(null == n){
            throw new IllegalArgumentException("空list不能remove!");
        }
        // 判断要删除的元素是不是第一个
        if(n.element.equals(e)){
            if(null != first.next){
                first = first.next;
            }
            size--;
            return e;
        }
        // 从第二个节点开始遍历链表
        while(null != n.next){
            if(e.equals(n.next.element)){
                n.next = n.next.next;
                size--;
                return e;
            }
            n = n.next;
        }
        System.out.println("没有找到此元素");
        return null;
    }


    // 这种方法不需要找到被删除节点的前驱节点,核心思想是将被删除节点的所有域值改变为它的后继节点的域值,将它的后继节点删除
    // 这种方法的局限性在于,必须给定一个节点,而非节点中的值,如果给定的是节点中的值,则必须遍历
    public void remove2(Node toDelnode){
        //如果被删除的时最后一个节点,那么它没有后继节点,这时仍然需要遍历找到这个它的前驱节点
        if(toDelnode.equals(last)){
            remove((E) toDelnode.element);
            return;
        }
        // next为被删除节点的后继节点
        Node nextNode = toDelnode.next;
        toDelnode.element = nextNode.element;
        toDelnode.next = nextNode.next;
        nextNode = null;
    }

    public int index(E e){
        if(null == e){
            return -1;
        }
        Node n = first;
        int index = 0;
        while(null != n){
            if(e.equals(n.element)){
                return index;
            }
            n = n.next;
            index++;
        }
        return -1;
    }

    public boolean contains(E e){
        return index(e)==-1?false:true;
    }

    // 顺序遍历链表
    public void printList(){
        Node n = first;
        while(null != n){
            System.out.print(n.element+",");
            n = n.next;
        }
    }
    // 逆序遍历链表
    private void printListRev(Node first){
        Node n = first;
        // 运用递归的思想
        if(null != n){
            printListRev(n.next);
            System.out.print(n.element+",");
        }
    }
	// 暴露给外部调用
    public void printListReverse(){
        this.printListRev(first);
    }

    public String toString(){
        String str = "";
        if(null == first){
            str = "null";
            return str;
        }
        Node n = first;
        while(null != n){
            str += n.element.toString()+",";
            n = n.next;
        }
        str = str.substring(0,str.lastIndexOf(','));
        return str;
    }

    public int size(){
        return size;
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值