单向链线性表-java语言版

122 阅读1分钟

单向链表是链表的一种,它由多个结点组成,每个结点都由一个数据域和一个指针域组成,数据域用来存储数据, 指针域用来指向其后继结点。链表的头结点的数据域不存储数据,指针域指向第一个真正存储数据的结点。

单向链表.png

-- API设计:

单向链表API.png

-- 代码:

/**
 * 单向链表,线性表
 * @param <T>
 */
public class LinkList<T> implements Iterable<T> {
    // 记录头结点
    private Node head;
    // 记录链表的长度
    private int N;

    // 构造方法
    public LinkList() {
        // 初始化头结点
        head = new Node(null,null);
        N = 0;
    }

    // 清空链表
    public void clear() {
        head.next = null;
        head.item = null;
        N = 0;
    }

    // 获取链表的长度
    public int length() {
        return N;
    }

    // 判断链表是否为空
    public boolean isEmpty() {
        return N == 0;
    }

    // 获取指定位置i处的元素
    public T get(int i) {
        // 判断获取位置是否合法
        if(i < 0 || i > N - 1) {
            throw new RuntimeException("位置不合法!");
        }
        Node n = head;
        // 找到i位置处的结点
        for(int index = 0;index <= i;index++) {
            n = n.next;
        }
        return n.item;
    }

    // 向链表中添加元素t
    public void insert(T t) {
        // 找到最后一个结点
        Node n = head;
        while (n.next != null) {
            n = n.next;
        }
        // 构建新结点
        Node newNode = new Node(t,null);
        n.next = newNode;
        // 链表长度+1
        N++;
    }

    // 向指定位置i处,添加元素t
    public void insert(int i,T t) {
        // 检查插入位置是否合法
        if(i < 0 || i > N) {
            throw new RuntimeException("位置不合法!");
        }
        // 寻找位置i之前的结点
        Node pre = head;
        for(int index = 0;index <= i - 1;index++) {
            pre = pre.next;
        }
        // 位置i的结点
        Node curr = pre.next;
        // 构建新结点,让新结点指向位置i处结点
        Node newNode = new Node(t,curr);
        // 让i之前结点指向新结点
        pre.next = newNode;
        // 长度+1
        N++;
    }

    // 删除指定位置的结点
    public T remove(int i) {
        // 检查删除位置是否合法
        if(i < 0 || i > N - 1) {
            throw new RuntimeException("位置不合法!");
        }
        // 寻找位置i之前的结点
        Node pre = head;
        for(int index = 0;index <= i - 1;index++) {
            pre = pre.next;
        }
        // 当前结点i
        Node curr = pre.next;
        // 让前一个结点,指向下一个结点
        pre.next = curr.next;
        // 长度-1
        N--;
        return curr.item;
    }

    // 查找元素t在链表中第一次出现的位置
    public int indexOf(T t) {
        Node n = head;
        for(int i = 0;n.next != null;i++) {
            n = n.next;
            if(n.item.equals(t)) {
                return i;
            }
        }
        return -1;
    }

    //==============================================================================
    // 实现for-each遍历的
    @Override
    public Iterator<T> iterator() {
        return new LIterator();
    }

    class LIterator implements Iterator<T> {
        private Node n;
        // 构造方法
        public LIterator() {
            this.n = head;
        }
        // 是否还有下一个
        @Override
        public boolean hasNext() {
            return n.next != null;
        }
        // 获取下一个结点
        @Override
        public T next() {
            n = n.next;
            return n.item;
        }
    }
    // 结点类
    class Node {
        // 存储元素
        private T item;
        // 记录链表的长度
        private Node next;
        // 构造方法
        public Node(T item,Node next) {
            this.item = item;
            this.next = next;
        }
    }
}

-- 测试代码:

public class LinkListTest {
    public static void main(String[] args) throws Exception {
        LinkList<String> list = new LinkList<>();
        list.insert(0, "张三");
        list.insert(1, "李四");
        list.insert(2, "王五");
        list.insert(3, "赵六");
        //测试length方法
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println(list.length());
        System.out.println("-------------------");
        //测试get方法
        System.out.println(list.get(2));
        System.out.println("------------------------");
        //测试remove方法
        String remove = list.remove(1);
        System.out.println(remove);
        System.out.println(list.length());
        System.out.println("----------------");

        for (String s : list) {
            System.out.println(s);
        }
    }
}

-- 运行效果图:

单向链表运行结果.png

@ 以上内容属于个人笔记