单链表Singly Linked List之JAVA实现

单链表算是一种很基础的数据结构了,下图是单链表的一般图示。

这里写图片描述

上学那会儿没怎么实际应用,对其功能和实现都是一知半解。
下面是以java来实现单链表的一些基本操作。

首先是结点类,每个结点包括数据域指针域,数据域存放数据,指针域指向下个结点,也就是存放下个结点的地址。

/**
 * 结点类
 */
class Node {
    private String data; // 数据域
    private Node next; // 指针域,指向下个结点

    public Node(String data, Node next) {
        super();
        this.data = data;
        this.next = next;
    }

    public Node(String data) {
        super();
        this.data = data;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    public void destroy() {
        this.data = null;
        this.next = null;
    }
}

接着是单链表类

/**
 * 单链表类
 */
class List {
    private Node head; // 头结点
    public int length; // 长度

    public List() {
        init();
    }

    private void init() {
        head = new Node("head", null);
    }

    public Node getHead() {
        return head;
    }

    public void setHead(Node head) {
        this.head = head;
    }

    /**
     * 头插法---插入结点
     * 
     * @param node
     */
    public boolean insertToHead(Node node) {
        Node n = head.getNext(); // 得到第一个结点
        if (n == null) { // 如果是空的话,直接插入头结点之后
            head.setNext(node);
        } else {
            node.setNext(n);
            head.setNext(node);
        }
        length++;
        return true;
    }

    /**
     * 尾插法---插入结点
     * @param node
     * @return
     */
    public boolean insertToTail(Node node) {
        Node n = head.getNext();
        if(n == null) {
            insertToHead(node);
            return true;
        }

        while(true) {
            if(n.getNext() == null){
                break;
            }
            n = n.getNext();
        }

        // insert
        n.setNext(node);
        length++;
        return true;
    }

    /**
     * 插入结点到指定位置(从0开始)
     * 
     * @param index
     */
    public boolean insertToIndex(int index, Node p) {
        if (index < 0 || index > length) {
            System.out.println("超出范围");
            return false;
        }

        if (index == 0) { // 插入到头结点之后
            insertToHead(p);
        } else if(index ==length) {
            insertToTail(p);
        } else {
            Node node = head;
            for (int i = -1; i < length - 1; i++) { // -1  to 3
                if (i + 1 == index) {
                    p.setNext(node.getNext());
                    node.setNext(p);
                    length++;
                    break;
                }
                node = node.getNext();
            }
        }

        return true;
    }

    /**
     * 结点编号是否在范围之内 (从0开始)
     * 
     * @param index
     * @return
     */
    public boolean findNode(int index) {
        if (index >= length || index < 0) {
            System.out.println("结点超出范围");
            return false;
        }
        return true;
    }

    /**
     * 删除指定编号的结点(从0开始)
     * 
     * @param index
     * @return
     */
    public boolean deleteNode(int index) {
        if (!findNode(index)) {
            return false;
        }

        Node node = head;
        // i从-1 到 length-2,判断其后的结点编号是否是待删除的结点
        for (int i = -1; i < length - 1; i++) {
            if (i + 1 == index) {
                // 如果其后的结点正是要删除的,赋值给p
                Node p = node.getNext();
                // 跳过此结点p
                node.setNext(p.getNext());
                // 销毁结点p
                p.destroy();
            }
            node = node.getNext();
        }
        length--;
        return true;
    }

    /**
     * 根据数据域删除结点
     * 
     * @param data
     * @return
     */
    public boolean deleteNode(String data) {
        boolean isExist = false;
        Node n = head;
        while (n != null) {
            if (n.getNext() != null && data.equals(n.getNext().getData())) {
                isExist = true;
                //
                n.setNext(n.getNext().getNext());
                length--;
                break;
            }
            n = n.getNext();
        }
        System.out.print(isExist ? "" : String
                .format("数据为\"%s\"的结点不存在\n", data));
        return isExist;
    }

    /**
     * 输出整个单链表
     */
    public void printList() {
        Node n = head;
        while (n != null) {
            System.out.print(n.getData());
            n = n.getNext();
            System.out.print(n == null ? "" : "-->");
        }
        System.out.println("\n长度为:" + length);
    }
}

代码中主要实现了单链表的插入(头插法,尾插法和指定位置插入),删除(根据数据和位置的删除)。

下面是头插法的算法图:
单链表Singly Linked List之JAVA实现_第1张图片

接下来是删除的图:
单链表Singly Linked List之JAVA实现_第2张图片

最后,附上测试类

/**
 * 测试类
 */
public class SinglyLinkedListDemo {
    public static void main(String[] args) {
        List list = new List();

        // 头插法插入6个结点
        list.insertToHead(new Node("1"));
        list.insertToHead(new Node("2"));
        list.insertToHead(new Node("3"));
        list.insertToHead(new Node("4"));
        list.insertToHead(new Node("5"));
        list.insertToHead(new Node("6"));
        // 输出整个单链表
        list.printList();
        System.out.println("****************************");

        // 头插法插入"99"
        System.out.println("头插法插入99");
        list.insertToHead(new Node("99"));
        list.printList();
        System.out.println("****************************");

        // 尾插法插入"77"
        System.out.println("尾插法插入77");
        list.insertToTail(new Node("77"));
        list.printList();
        System.out.println("****************************");

        // 删除编号3的结点,从0开始
        System.out.println("删除第三个结点");
        list.deleteNode(3);
        // 输出整个单链表
        list.printList();
        System.out.println("****************************");

        System.out.println("删除数据为\"111\"的结点");
        list.deleteNode("111");
        list.printList();
        System.out.println("****************************");

        // 在目标索引位置插入结点,从0开始
        System.out.println("在位置3插入数据为\"88\"的结点");
        list.insertToIndex(3, new Node("88"));
        // 输出整个单链表
        list.printList();
    }

最后是测试结果

head-->6-->5-->4-->3-->2-->1
长度为:6
****************************
头插法插入99
head-->99-->6-->5-->4-->3-->2-->1
长度为:7
****************************
尾插法插入77
head-->99-->6-->5-->4-->3-->2-->1-->77
长度为:8
****************************
删除第三个结点
head-->99-->6-->5-->3-->2-->1-->77
长度为:7
****************************
删除数据为"111"的结点
数据为"111"的结点不存在
head-->99-->6-->5-->3-->2-->1-->77
长度为:7
****************************
在位置3插入数据为"88"的结点
head-->99-->6-->5-->88-->3-->2-->1-->77
长度为:8

你可能感兴趣的:(数据结构)