数据结构02-单链表

上一篇文章讲述了动态数组ArrayList的简单实现,这次讲述一下单链表这种链式的存储结构,在此之前先弄懂以下几个基本问题:

1.什么是单链表?

是一种链式存储的数据结构,具有指针域和节点域两块内存空间,相对于其他链表来说,单链表只有一个指针域,且总是指向下一个结点(循环链表可以指向前面的结点);

2.与动态数组相比,有什么优势,什么劣势?

优势:在于首尾元素的插入与删除和不损性能的长度扩展,对于双向链表而言,首尾插入、删除的效率都是非常高的,而插入中间元素则相对低效,在长度扩展方面动态数组需要建立新数组,再将所有元素‘举家迁移’至新数组,而对于链表而言,不需要连续的存储空间,通过指针域来保存任意内存位置上的下一个结点;

劣势:获取中间数据效率低和占用内存大,由于没有索引,所以获取第n个位置的元素需要将指针移动n-1次,而动态数组则直接通过索引访问,占用内存大很好理解,相对于动态数组而言多了一个指针域;

实现过程如下:

1.建立MyList接口,提供线性表基本操作的规范:

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

2.定义实现类:

package A01.LSQ;

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

public class MyLinkedList<E> implements MyList<E>, Iterable<E>
{
    // 头结点
    private Node<E> head;
    // 链表长度
    private int size;

    public MyLinkedList()
    {
        head = new Node<>();
    }

    // 末尾位置插入元素
    @Override
    public E add(E data)
    {
        Node<E> temp = head;
        while (temp.next != null)
            temp = temp.next;
        temp.next = new Node<>(data);
        size++;
        return data;
    }

    // 自定义位置插入元素
    @Override
    public E add(int index, E data)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("越界");
        int count = 0;
        Node<E> temp = head;
        while (temp.next != null)
        {
            if (count++ == index)
            {
                Node<E> p = new Node<>(data);
                p.next = temp.next;
                temp.next = p;
                size++;
                break;
            }
            temp = temp.next;
        }
        return data;
    }

    // 返回大小
    @Override
    public int size()
    {
        return size;
    }

    // 获取元素
    @Override
    public E get(int index)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("越界");
        int count = 0;
        Node<E> temp = head;
        while (temp.next != null)
        {
            temp = temp.next;
            if (count++ == index)
            {
                return temp.data;
            }
        }
        return null;
    }

    // 通过位置删除元素
    @Override
    public boolean remove(int index)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("越界");
        int count = 0;
        Node<E> temp = head;
        while (temp.next != null)
        {
            if (count++ == index)
            {
                temp.next = temp.next.next;
                size--;
                break;
            }
            temp = temp.next;
        }
        return true;
    }

    // 通过数据对比删除元素
    @Override
    public boolean remove(E data)
    {
        Node<E> temp = head;
        int count = 0;
        while (temp.next != null)
        {
            temp = temp.next;
            if (temp.data.equals(data))
            {
                return remove(count);
            }
            count++;
        }
        return false;
    }

    // 修改元素
    @Override
    public E set(int index, E data)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("越界");
        int count = 0;
        Node<E> temp = head;
        while (temp.next != null)
        {
            temp = temp.next;
            if (count++ == index)
            {
                temp.data = data;
                return temp.data;
            }
        }
        return null;
    }

    // 内部结点类
    private class Node<E>
    {
        Node<E> next;
        E data;

        public Node()
        {
            this(null);
        }

        public Node(E data)
        {
            this.data = data;
            next = null;
        }
    }

    // 遍历链表
    public void disPlay()
    {
        Node<E> temp = head;
        while (temp.next != null)
        {
            temp = temp.next;
            System.out.println(temp.data);
        }
    }

    // 增强for循环需要提供的方法,返回一个Iterator接口对象
    @Override
    public Iterator<E> iterator()
    {
        return new MyLinkedListIterator();
    }

    // 内部类实现Iterator接口,实现remove、hasNext、next三个基本方法
    private class MyLinkedListIterator implements Iterator<E>
    {
        private int current = 0;

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

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

        @Override
        public E next()
        {
            if (!hasNext())
                throw new NoSuchElementException();
            return get(current++);
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值