手写双向链表

采用双向链表的形式尝试写一下 java中LinkedList

public class LinkedList<E> {


    /**
     * 节点
     */
    private static class Node<E> {
        E item;
        Node<E> pre;
        Node<E> next;

        public Node(Node<E> pre, E item, Node<E> next) {
            this.item = item;
            this.pre = pre;
            this.next = next;
        }
    }


    public LinkedList() {
    }

    //头节点
    Node<E> first;
    //尾节点
    Node<E> last;
    //大小
    int size;


    /**
     * 添加数据在最后
     */
    public void add(E e) {
        linkLast(e);
    }

    /**
     * 添加到最后
     *
     * @param e
     */
    private void linkLast(E e) {
        Node<E> newNode = new Node<>(last, e, null);
        Node<E> temp = last;
        last = newNode;

        if (temp == null) {
            first = newNode;
        } else {
            temp.next = newNode;
        }
        size++;
    }

    /**
     * 获取对象
     */
    public E get(int index) {
        if (index < 0 || index > size - 1) {
            return null;
        }
        return node(index).item;
    }

    /**
     * 获取index位置上的节点
     *
     * @param index
     */
    private Node<E> node(int index) {
        Node<E> node;
        //如果index在链表前半部分
        if (index < (size >> 1))//除以2
        {
            node = first;
            for (int i = 0; i < index; i++) {
                node = node.next;
            }
        } else {
            node = last;
            for (int i = size - 1; i > index; i--) {
                node = node.pre;
            }
        }
        return node;
    }


    /**
     * 添加数据在index位置
     */

    public void add(int index, E e) {
        if (index < 0 || index > size) {
            return;
        }

        if (index == size) {
            linkLast(e);
        } else {
            Node<E> target = node(index);
            Node<E> preNode = target.pre;
            Node<E> newNode = new Node<>(preNode, e, target);

            if (preNode == null) {
                first = newNode;
                target.pre = newNode;
            } else {
                preNode.next = newNode;
                target.pre = newNode;
            }
            size++;
        }
    }

    /**
     * 删除元素
     */
    public void remove(int index) {
        if (size == 0 || index < 0 || index > size - 1) {
            return;
        }
        Node<E> node = node(index);
        unLinkNode(node);
    }

    private void unLinkNode(Node<E> node) {
        Node<E> preNode = node.pre;
        Node<E> nextNode = node.next;

        if (preNode == null) {
            first = nextNode;
        } else if (nextNode == null) {
            last = preNode;
        } else {
            preNode.next = nextNode;
            nextNode.pre = preNode;
        }
        size--;
    }

}

 

写个test测试下功能 

 @Test
    public void testLinkedList(){

        LinkedList<Integer> list=new LinkedList<>();
        list.add(3);
        list.add(80);
        list.add(1);
        list.add(7);
        list.add(32);
        log(list);
        list.add(0,12);
        log(list);

        list.add(3,50);
        log(list);

        list.remove(3);
        log(list);

        list.remove(0);
        log(list);
    }

    public void log(LinkedList linkedList){
        for (int i = 0; i < linkedList.size; i++) {
            System.out.print(linkedList.get(i)+" ");
        }
        System.out.println("");
    }

 打印结果

3 80 1 7 32 
12 3 80 1 7 32 
12 3 80 50 1 7 32 
12 3 80 1 7 32 
3 80 1 7 32 

判断单链表是否存在环?

【快慢指针】:需要两个指针,一个快指针:每次走两步,一个慢指针:每次走一步。 
如果快慢指针能够相遇(如果快指针能够追上慢指针),就证明有环。 
但是!!!这个方法存在问题。如果链表够长,而环又足够小,那么快指针将永远不会追上慢指针 
所以,快慢指针只适合用于环出现在链表尾部的情况,也就是单链表环的问题,而无法解决链表存在循环的问题。
 

   public class Link_list_circle {

        public boolean hascycle(ListNode head) {
            //快慢指针
            ListNode slow, fast;
            slow = fast = head;
            while (fast != null && fast.next != null) {
                slow = slow.next;
                fast = fast.next.next;
                if (fast == slow) return ture;
            }
            return false;
        }

    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值