数据结构03-双向链表

之前有说过链表的首尾操作是十分快速,其实这句话不准确,对于单链表而言,只有一侧的操作快速,另一侧的操作依旧需要大量的移动指针(如果数据多的话);

双向链表与单向链表的区别:

1.增加了一个指针域保存上一个结点,内存占用大于单链表;

2.首尾两侧操作都很快速,而单链表只能保证一侧;

 

接下来实现一个双向链表:

1.定义MyList接口,提供线性表操作规范:

见作者的第一篇博客,《数据结构01-自定义ArrayList

 

2.定义实现类,MyDLinkedList,便于与单链表区分,加入字母D:

package A01.LSQ;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class MyDLinkedList<E> implements MyList<E>, Iterable<E>
{
    // 测试方法
    public static void main(String[] args)
    {
        MyDLinkedList<Integer> list = new MyDLinkedList<>();
        list.add(4);
        list.add(6);
        list.add(9);
        list.add(10);
        list.set(0, -1);
        for (Integer i:list)
        {
            System.out.println(i);
        }
    }

    // 定义开始、结束的结点
    private Node<E> bigen;
    private Node<E> end;
    // 链表长度
    private int size;

    public MyDLinkedList()
    {
        bigen = new Node<>(null, null, null);
        end = new Node<>(null, bigen, null);
        bigen.next = end;
        size = 0;
    }

    public E get(int index)
    {
        return getNode(index).data;
    }

    private Node<E> getNode(int index)
    {
        return getNode(index, 0, size);
    }

    // 根据下标获取一个结点
    private Node<E> getNode(int index, int low, int upper)
    {
        Node<E> p;
        if (index < low || index > upper)
            throw new IndexOutOfBoundsException("越界");
        // 从首尾两侧寻找至目标结点最近的距离
        if (index > size / 2)
        {
            p = bigen.next;
            for (int i = 0; i < index; i++)
            {
                p = p.next;
            }
        } else
        {
            p = end;
            for (int i = size; i > index; i--)
            {
                p = p.prev;
            }
        }
        return p;
    }

    // 与以往不同,借用有参构造器来插入结点,使插入方法根据简洁易懂
    public void addBefore(Node<E> p, E data)
    {
        Node<E> temp = new Node<>(data, p.prev, p);
        temp.prev.next = temp;
        p.prev = temp;
        size++;
    }

    public E add(E data)
    {
        return add(size, data);
    }

    public E add(int index, E data)
    {
        addBefore(getNode(index), data);
        return data;
    }

    // 倒序遍历
    public void disPlay()
    {
        System.out.println("-----------");
        Node<E> temp = end;
        // 由于头结点存在,且data为null,所以要过滤掉头结点
        while (temp.prev.prev!= null)
        {
            temp = temp.prev;
            System.out.println(temp.data);
        }
    }

    private class Node<E>
    {
        Node<E> next;
        Node<E> prev;
        E data;

        public Node(E data, Node<E> prev, Node<E> next)
        {
            this.next = next;
            this.prev = prev;
            this.data = data;
        }
    }

    @Override
    public int size()
    {
        return size;
    }

    @Override
    public boolean remove(int index)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("越界");
        remove(getNode(index));
        return true;
    }

    @Override
    public boolean remove(E data)
    {
        if (size == 0)
            return false;
        int conut = 0;
        Node<E> temp = bigen;
        while (temp.next != null)
        {
            temp = temp.next;
            if (temp.data.equals(data))
            {
                remove(conut);
                return true;
            }
            conut++;
        }
        return false;
    }

    @Override
    public E set(int index, E data)
    {
        if (size == 0)
            return null;
        getNode(index).data = data;
        return data;
    }

    private void remove(Node<E> p)
    {
        p.next.prev = p.prev;
        p.prev.next = p.next;
        size--;
    }

    @Override
    public Iterator<E> iterator()
    {
        return new MyDLinkedList.MyLinkedListIterator();
    }

    private class MyLinkedListIterator implements Iterator<E>
    {
        private int current = 0;

        @Override
        public void remove()
        {
            MyDLinkedList.this.remove(--current);
        }

        @Override
        public boolean hasNext()
        {
            return current < size;
        }

        @Override
        public E next()
        {
            if (!hasNext())
                throw new NoSuchElementException();
            return get(current++);
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值