package com.ds.link;
/**
 * <p>
 * <strong>数据结构之Java单链表</strong>
 * </p>
 * <p>
 * 单链表提供了在列表头的高效插入和删除操作,不过在单链表的末尾的插入操作效率很低.
 * </p>
 * <p>
 * 单链表指针域保存着下一节点的引用,尾结点的指针域等于null
 * </p>
 *
 * @author zhb 2013
 */
public class SingleLink<T> {
    /**
     * 结点类
     */
    private class Node<T> {
        private T data;// 数据域
        private Node<T> next; // 指针域保存着下一节点的引用
        public Node(T data, Node<T> next) {
            this.data = data;
            this.next = next;
        }
        public Node(T data) {
            this(data, null);
        }
    }
    // 下面是SingleLinkedList类的数据成员和方法
    private Node<T> header, tail;
    private int size;
    public SingleLink() {
        this.header = null;
        this.tail = null;
        this.size = 0;
    }
    /**
     * 判断链表是否为空
     */
    public boolean isEmpty() {
        return header == null;
    }
    /**
     * 创建头指针,该方法只用一次!
     */
    public void addToHeader(T item) {
        header = new Node<T>(item);
        size += 1;
        if (tail == null)
            tail = header;
    }
    /**
     * 添加尾指针,该方法使用多次
     */
    public void addToTail(T item) {
        if (!isEmpty()) {// 若链表非空那么将尾指针的next初使化为一个新的元素
            tail.next = new Node<T>(item); // 然后将尾指针指向现在它自己的下一个元素
            tail = tail.next;
            size += 1;
        } else {// 如果为空则创建一个新的!并将头尾同时指向它
            header = tail = new Node<T>(item);
            size += 1;
        }
    }
    /**
     * 打印列表
     */
    public void print() {
        if (isEmpty()) {
            System.out.println("null");
        } else {
            Node<T> current = header;
            while (current != null) {
                System.out.println("sigleLink size:" + this.size + "\t data:" + current.data);
                current = current.next;
            }
        }
    }
    /**
     * 在表头插入结点,效率非常高
     */
    public void addFirst(T item) {
        Node<T> newNode = new Node<T>(item);
        newNode.next = header;
        header = newNode;
        size += 1;
    }
    /**
     * 在表尾插入结点,效率很低
     */
    public void addLast(T item) {
        Node<T> newNode = new Node<T>(item);
        while (header.next != null)
            header = header.next;
        header.next = newNode;
        newNode.next = null;
        size += 1;
    }
    /**
     * 在表头删除结点,效率非常高
     */
    public void deleteFirst() {
        if (!isEmpty()) {
            header = header.next;
            size -= 1;
        } else
            System.out.println("The list have been emptied!");
    }
    /**
     * 在表尾删除结点,效率很低
     */
    public void deleteLast() {
        Node<T> current = header;
        Node<T> pre = null;
        while (current != null) {
            pre = current;
            current = current.next;
            if (current.next == null) {
                pre.next = null;
                size -= 1;
            }
        }
    }
    /**
     * 在链表中任意位置插入,即在n后面插入
     */
    public void insert(int n, T item) {
        if (n < 0 || n > size) {
            System.out.println("insert error!");
        } else {
            Node<T> current = header;
            Node<T> newNode = new Node<T>(item);
            for (int index = 0; index < n -1; index++) {
                current = current.next;
            }
            newNode.next = current.next;
            current.next = newNode;
            this.size +=1;
        }
    }
                   
    /**
     * 测试代码
     */
    public static void main(String[] args) {
        SingleLink<String> sl = new SingleLink<String>();
                       
        sl.addToHeader("A");
        sl.addToTail("B");
        sl.addFirst("D");
        sl.insert(2, "C");
        sl.insert(1, "E");
        sl.deleteFirst();
                       
        sl.print();
    }
}


有问题可以随时交流!