Java数据结构和算法三 链表

1 链表简介

链表是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针。使用链表结构可以克服数组需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表一般分为单链表、双端链表、双向链表、有序链表、单向循环链表等。

2 单链表

单链表的节点分为两个部分,第一个部分保存或者显示关于节点的信息,另一个部分存储下一个节点的地址。最后一个节点存储地址的部分指向空值。单向链表只可向一个方向遍历,一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。

2.1 代码示例
package com.example.array;

/**
 * 单向链表
 */
public class SingleLinkedList {

    /**
     * 元素个数
     */
    private int size;
    /**
     * 头节点
     */
    private Node head;

    private class Node {

        /**
         * 数据
         */
        private int data;
        /**
         * 下一个节点
         */
        private Node next;

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 添加头节点
     * @param data
     * @return
     */
    public boolean addHead(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
        } else {
            newNode.next = head;
            head = newNode;
        }
        size++;
        return true;
    }

    /**
     * 添加尾节点
     * @param data
     * @return
     */
    public boolean addTail(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
        } else {
            Node current = head;
            while (true) {
                if (current.next == null) {
                    current.next = newNode;
                    break;
                }
                current = current.next;
            }
        }
        size++;
        return true;
    }

    /**
     * 删除头节点
     * @return
     */
    public boolean deleteHead() {
        if (isEmpty()) {
            System.out.println("链表为空,无法删除头节点!");
            return false;
        }
        head = head.next;
        size--;
        return true;
    }

    /**
     * 根据data值删除节点
     * @param data
     * @return
     */
    public boolean delete(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值删除节点!");
            return false;
        }
        Node current = head;
        Node previous = head;
        while (current.data != data) {
            if (current.next == null) {
                System.out.println("根据data值未找到节点,无法根据data值删除节点!");
                return false;
            } else {
                previous = current;
                current = current.next;
            }
        }
        if (current == head) {
            head = current.next;
            current.next = null;
        } else {
            previous.next = current.next;
        }
        size--;
        return true;
    }

    /**
     * 根据data值查找节点
     * @param data
     * @return
     */
    public boolean find(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值查找节点!");
            return false;
        }
        Node current = head;
        int tempSise = size;
        while (tempSise > 0) {
            if (data == current.data) {
                return true;
            } else {
                current = current.next;
            }
            tempSise--;
        }
        return false;
    }

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

    /**
     * 获取链表元素个数
     * @return
     */
    public int getSize() {
        return size;
    }

    /**
     * 遍历链表
     */
    public void display() {
        if (isEmpty()) {
            System.out.println("遍历结果:链表为空!");
            return;
        }
        if (size == 1) {
            System.out.println("遍历结果:" + head.data);
            return;
        }
        Node node = head;
        int tempSize = size;
        System.out.print("遍历结果:");
        while (tempSize > 0) {
            System.out.print(node.data + "\t");
            node = node.next;
            tempSize--;
        }
        System.out.println();
    }

}
2.2 测试
package com.example.array;

import org.junit.Test;

/**
 * 测试单向链表
 */
public class TestSingleLinkedList {

    /**
     * 测试添加头节点
     */
    @Test
    public void testAddHead() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addHead(1);
        singleLinkedList.display();
        singleLinkedList.addHead(2);
        singleLinkedList.display();
    }

    /**
     * 测试添加尾节点
     */
    @Test
    public void testAddTail() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.addTail(1);
        singleLinkedList.display();
        singleLinkedList.addTail(2);
        singleLinkedList.display();
    }

    /**
     * 测试删除头节点
     */
    @Test
    public void testDeleteHead() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.deleteHead();
        singleLinkedList.addTail(1);
        singleLinkedList.addTail(2);
        singleLinkedList.addTail(3);
        singleLinkedList.display();
        singleLinkedList.deleteHead();
        singleLinkedList.display();
        singleLinkedList.deleteHead();
        singleLinkedList.display();
        singleLinkedList.deleteHead();
        singleLinkedList.display();
    }

    /**
     * 测试根据data值删除节点
     */
    @Test
    public void testDelete() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.delete(2);
        singleLinkedList.addTail(1);
        singleLinkedList.addTail(2);
        singleLinkedList.addTail(3);
        singleLinkedList.display();
        singleLinkedList.delete(2);
        singleLinkedList.display();
        singleLinkedList.delete(10);
        singleLinkedList.display();
    }

    /**
     * 测试根据data值查找节点
     */
    @Test
    public void testFind() {
        SingleLinkedList singleLinkedList = new SingleLinkedList();
        singleLinkedList.find(3);
        singleLinkedList.addTail(1);
        singleLinkedList.addTail(2);
        singleLinkedList.addTail(3);
        singleLinkedList.display();
        boolean flag = singleLinkedList.find(3);
        System.out.println(flag);
        flag = singleLinkedList.find(5);
        System.out.println(flag);
    }
}

3 双端链表

单链表如果想在尾部添加一个节点,那么必须从头部一直遍历到尾部,找到尾节点,然后在尾节点后面插入一个节点。如果我们在设计链表的时候多个对尾节点的引用,那么会简单很多。

3.1 代码示例
package com.example.array;

/**
 * 双端链表
 */
public class DoublePointLinkedList {

    /**
     * 元素个数
     */
    private int size;
    /**
     * 头节点
     */
    private Node head;
    /**
     * 尾节点
     */
    private Node tail;

    private class Node {

        /**
         * 数据
         */
        private int data;
        /**
         * 下一个节点
         */
        private Node next;

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 添加头节点
     * @param data
     * @return
     */
    public boolean addHead(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
            tail = newNode;
        } else {
            newNode.next = head;
            head = newNode;
        }
        size++;
        return true;
    }

    /**
     * 添加尾节点
     * @param data
     * @return
     */
    public boolean addTail(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
            tail = newNode;
        } else {
            tail.next = newNode;
            tail = newNode;
        }
        size++;
        return true;
    }

    /**
     * 删除头节点
     * @return
     */
    public boolean deleteHead() {
        if (isEmpty()) {
            System.out.println("链表为空,无法删除头节点!");
            return false;
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            head = head.next;
        }
        size--;
        return true;
    }

    /**
     * 根据data值删除节点
     * @param data
     * @return
     */
    public boolean delete(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值删除节点!");
            return false;
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            Node current = head;
            Node previous = head;
            while (current.data != data) {
                if (current.next == null) {
                    System.out.println("根据data值未找到节点,无法根据data值删除节点!");
                    return false;
                } else {
                    previous = current;
                    current = current.next;
                }
            }
            if (current == head) {
                head = current.next;
                current.next = null;
            } else if (current == tail) {
                tail = previous;
                previous.next = null;
            } else {
                previous.next = current.next;
            }
        }
        size--;
        return true;
    }

    /**
     * 根据data值查找节点
     * @param data
     * @return
     */
    public boolean find(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值查找节点!");
            return false;
        }
        Node current = head;
        int tempSise = size;
        while (tempSise > 0) {
            if (data == current.data) {
                return true;
            } else {
                current = current.next;
            }
            tempSise--;
        }
        return false;
    }

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

    /**
     * 获取链表元素个数
     * @return
     */
    public int getSize() {
        return size;
    }

    /**
     * 遍历链表
     */
    public void display() {
        if (isEmpty()) {
            System.out.println("遍历结果:链表为空!");
            return;
        }
        if (size == 1) {
            System.out.println("遍历结果:" + head.data);
            return;
        }
        Node node = head;
        int tempSize = size;
        System.out.print("遍历结果:");
        while (tempSize > 0) {
            System.out.print(node.data + "\t");
            node = node.next;
            tempSize--;
        }
        System.out.println();
    }
}
3.2 测试
package com.example.array;

import org.junit.Test;

/**
 * 测试双端链表
 */
public class TestDoublePointLinkedList {

    /**
     * 测试添加头节点
     */
    @Test
    public void testAddHead() {
        DoublePointLinkedList doublePointLinkedList = new DoublePointLinkedList();
        doublePointLinkedList.addHead(1);
        doublePointLinkedList.display();
        doublePointLinkedList.addHead(2);
        doublePointLinkedList.display();
    }

    /**
     * 测试添加尾节点
     */
    @Test
    public void testAddTail() {
        DoublePointLinkedList doublePointLinkedList = new DoublePointLinkedList();
        doublePointLinkedList.addTail(1);
        doublePointLinkedList.display();
        doublePointLinkedList.addTail(2);
        doublePointLinkedList.display();
    }

    /**
     * 测试删除头节点
     */
    @Test
    public void testDeleteHead() {
        DoublePointLinkedList doublePointLinkedList = new DoublePointLinkedList();
        doublePointLinkedList.deleteHead();
        doublePointLinkedList.addTail(1);
        doublePointLinkedList.addTail(2);
        doublePointLinkedList.addTail(3);
        doublePointLinkedList.display();
        doublePointLinkedList.deleteHead();
        doublePointLinkedList.display();
        doublePointLinkedList.deleteHead();
        doublePointLinkedList.display();
        doublePointLinkedList.deleteHead();
        doublePointLinkedList.display();
    }

    /**
     * 测试根据data值删除节点
     */
    @Test
    public void testDelete() {
        DoublePointLinkedList doublePointLinkedList = new DoublePointLinkedList();
        doublePointLinkedList.delete(2);
        doublePointLinkedList.addTail(1);
        doublePointLinkedList.addTail(2);
        doublePointLinkedList.addTail(3);
        doublePointLinkedList.display();
        doublePointLinkedList.delete(2);
        doublePointLinkedList.display();
        doublePointLinkedList.delete(10);
        doublePointLinkedList.display();
        doublePointLinkedList.delete(1);
        doublePointLinkedList.display();
        doublePointLinkedList.delete(3);
        doublePointLinkedList.display();
    }

    /**
     * 测试根据data值查找节点
     */
    @Test
    public void testFind() {
        DoublePointLinkedList doublePointLinkedList = new DoublePointLinkedList();
        doublePointLinkedList.find(3);
        doublePointLinkedList.addTail(1);
        doublePointLinkedList.addTail(2);
        doublePointLinkedList.addTail(3);
        doublePointLinkedList.display();
        boolean flag = doublePointLinkedList.find(3);
        System.out.println(flag);
        flag = doublePointLinkedList.find(5);
        System.out.println(flag);
    }
}

4 双向链表

单链表只能从一个方向遍历,双向链表可以从两个方向遍历。

4.1 代码示例
package com.example.array;

/**
 * 双向链表
 */
public class TwoWayLinkedList {

    /**
     * 元素个数
     */
    private int size;
    /**
     * 头节点
     */
    private Node head;
    /**
     * 尾节点
     */
    private Node tail;

    private class Node {

        /**
         * 数据
         */
        private int data;
        /**
         * 下一个节点
         */
        private Node next;
        /**
         * 上一个节点
         */
        private Node prev;

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 添加头节点
     * @param data
     * @return
     */
    public boolean addHead(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
            tail = newNode;
        } else {
            head.prev = newNode;
            newNode.next = head;
            head = newNode;
        }
        size++;
        return true;
    }

    /**
     * 添加尾节点
     * @param data
     * @return
     */
    public boolean addTail(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            head = newNode;
            tail = newNode;
        } else {
            newNode.prev = tail;
            tail.next = newNode;
            tail = newNode;
        }
        size++;
        return true;
    }

    /**
     * 删除头节点
     * @return
     */
    public boolean deleteHead() {
        if (isEmpty()) {
            System.out.println("链表为空,无法删除头节点!");
            return false;
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            head = head.next;
            head.prev = null;
        }
        size--;
        return true;
    }

    /**
     * 删除尾节点
     * @return
     */
    public boolean deleteTail() {
        if (isEmpty()) {
            System.out.println("链表为空,无法删除尾节点!");
            return false;
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            tail = tail.prev;
            tail.next = null;
        }
        size--;
        return true;
    }

    /**
     * 根据data值删除节点
     * @param data
     * @return
     */
    public boolean delete(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值删除节点!");
            return false;
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            Node current = head;
            Node previous = head;
            while (current.data != data) {
                if (current.next == null) {
                    System.out.println("根据data值未找到节点,无法根据data值删除节点!");
                    return false;
                } else {
                    previous = current;
                    current = current.next;
                }
            }
            if (current == head) {
                head = current.next;
                current.next = null;
            } else if (current == tail) {
                tail = previous;
                previous.next = null;
            } else {
                current.next.prev = previous;
                previous.next = current.next;
            }
        }
        size--;
        return true;
    }

    /**
     * 根据data值查找节点
     * @param data
     * @return
     */
    public boolean find(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值查找节点!");
            return false;
        }
        Node current = head;
        int tempSise = size;
        while (tempSise > 0) {
            if (data == current.data) {
                return true;
            } else {
                current = current.next;
            }
            tempSise--;
        }
        return false;
    }

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

    /**
     * 获取链表元素个数
     * @return
     */
    public int getSize() {
        return size;
    }

    /**
     * 遍历链表
     */
    public void display() {
        if (isEmpty()) {
            System.out.println("遍历结果:链表为空!");
            return;
        }
        if (size == 1) {
            System.out.println("遍历结果:" + head.data);
            return;
        }
        Node node = head;
        int tempSize = size;
        System.out.print("遍历结果:");
        while (tempSize > 0) {
            System.out.print(node.data + "\t");
            node = node.next;
            tempSize--;
        }
        System.out.println();
    }
}
4.2 测试
package com.example.array;

import org.junit.Test;

/**
 * 测试双向链表
 */
public class TestTwoWayLinkedList {

    /**
     * 测试添加头节点
     */
    @Test
    public void testAddHead() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.addHead(1);
        twoWayLinkedList.display();
        twoWayLinkedList.addHead(2);
        twoWayLinkedList.display();
    }

    /**
     * 测试添加尾节点
     */
    @Test
    public void testAddTail() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.addTail(1);
        twoWayLinkedList.display();
        twoWayLinkedList.addTail(2);
        twoWayLinkedList.display();
    }

    /**
     * 测试删除头节点
     */
    @Test
    public void testDeleteHead() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.deleteHead();
        twoWayLinkedList.addTail(1);
        twoWayLinkedList.addTail(2);
        twoWayLinkedList.addTail(3);
        twoWayLinkedList.display();
        twoWayLinkedList.deleteHead();
        twoWayLinkedList.display();
        twoWayLinkedList.deleteHead();
        twoWayLinkedList.display();
        twoWayLinkedList.deleteHead();
        twoWayLinkedList.display();
    }

    /**
     * 测试删除头节点
     */
    @Test
    public void testDeleteTail() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.deleteHead();
        twoWayLinkedList.addTail(1);
        twoWayLinkedList.addTail(2);
        twoWayLinkedList.addTail(3);
        twoWayLinkedList.display();
        twoWayLinkedList.deleteTail();
        twoWayLinkedList.display();
        twoWayLinkedList.deleteTail();
        twoWayLinkedList.display();
        twoWayLinkedList.deleteTail();
        twoWayLinkedList.display();
    }

    /**
     * 测试根据data值删除节点
     */
    @Test
    public void testDelete() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.delete(2);
        twoWayLinkedList.addTail(1);
        twoWayLinkedList.addTail(2);
        twoWayLinkedList.addTail(3);
        twoWayLinkedList.display();
        twoWayLinkedList.delete(2);
        twoWayLinkedList.display();
        twoWayLinkedList.delete(10);
        twoWayLinkedList.display();
        twoWayLinkedList.delete(1);
        twoWayLinkedList.display();
        twoWayLinkedList.delete(3);
        twoWayLinkedList.display();
    }

    /**
     * 测试根据data值查找节点
     */
    @Test
    public void testFind() {
        TwoWayLinkedList twoWayLinkedList = new TwoWayLinkedList();
        twoWayLinkedList.find(3);
        twoWayLinkedList.addTail(1);
        twoWayLinkedList.addTail(2);
        twoWayLinkedList.addTail(3);
        twoWayLinkedList.display();
        boolean flag = twoWayLinkedList.find(3);
        System.out.println(flag);
        flag = twoWayLinkedList.find(5);
        System.out.println(flag);
    }
}

5 有序链表

有序链表数据是按照关键值有序排列的。一般在大多数需要使用有序数组的场合也可以使用有序链表。有序链表优于有序数组的地方是插入的速度(因为元素不需要移动),另外链表可以扩展到全部有效的使用内存,而数组只能局限于一个固定的大小中。

5.1 代码示例
package com.example.array;

/**
 * 有序链表
 */
public class OrderLinkedList {

    /**
     * 元素个数
     */
    private int size;
    /**
     * 头节点
     */
    private Node head;

    private class Node {

        /**
         * 数据
         */
        private int data;
        /**
         * 下一个节点
         */
        private Node next;

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 有序添加节点
     * @param data
     */
    public boolean insert(int data) {
        Node newNode = new Node(data);
        Node pre = null;
        Node current = head;
        while (current != null && data > current.data) {
            pre = current;
            current = current.next;
        }
        if (pre == null) {
            head = newNode;
            head.next = current;
        } else {
            pre.next = newNode;
            newNode.next = current;
        }
        size++;
        return true;
    }

    /**
     * 删除头节点
     * @return
     */
    public boolean deleteHead() {
        if (isEmpty()) {
            System.out.println("链表为空,无法删除头节点!");
            return false;
        }
        head = head.next;
        size--;
        return true;
    }

    /**
     * 根据data值删除节点
     * @param data
     * @return
     */
    public boolean delete(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值删除节点!");
            return false;
        }
        Node current = head;
        Node previous = head;
        while (current.data != data) {
            if (current.next == null) {
                System.out.println("根据data值未找到节点,无法根据data值删除节点!");
                return false;
            } else {
                previous = current;
                current = current.next;
            }
        }
        if (current == head) {
            head = current.next;
            current.next = null;
        } else {
            previous.next = current.next;
        }
        size--;
        return true;
    }

    /**
     * 根据data值查找节点
     * @param data
     * @return
     */
    public boolean find(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值查找节点!");
            return false;
        }
        Node current = head;
        int tempSise = size;
        while (tempSise > 0) {
            if (data == current.data) {
                return true;
            } else {
                current = current.next;
            }
            tempSise--;
        }
        return false;
    }

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

    /**
     * 获取链表元素个数
     * @return
     */
    public int getSize() {
        return size;
    }

    /**
     * 遍历链表
     */
    public void display() {
        if (isEmpty()) {
            System.out.println("遍历结果:链表为空!");
            return;
        }
        if (size == 1) {
            System.out.println("遍历结果:" + head.data);
            return;
        }
        Node node = head;
        int tempSize = size;
        System.out.print("遍历结果:");
        while (tempSize > 0) {
            System.out.print(node.data + "\t");
            node = node.next;
            tempSize--;
        }
        System.out.println();
    }
}
5.2 测试
package com.example.array;

import org.junit.Test;

/**
 * 测试有序链表
 */
public class TestOrderLinkedList {

    /**
     * 测试有序添加节点
     */
    @Test
    public void testInsert() {
        OrderLinkedList orderLinkedList = new OrderLinkedList();
        orderLinkedList.insert(1);
        orderLinkedList.display();
        orderLinkedList.insert(2);
        orderLinkedList.display();
    }

    /**
     * 测试删除头节点
     */
    @Test
    public void testDeleteHead() {
        OrderLinkedList orderLinkedList = new OrderLinkedList();
        orderLinkedList.deleteHead();
        orderLinkedList.insert(1);
        orderLinkedList.insert(2);
        orderLinkedList.insert(3);
        orderLinkedList.display();
        orderLinkedList.deleteHead();
        orderLinkedList.display();
        orderLinkedList.deleteHead();
        orderLinkedList.display();
        orderLinkedList.deleteHead();
        orderLinkedList.display();
    }

    /**
     * 测试根据data值删除节点
     */
    @Test
    public void testDelete() {
        OrderLinkedList orderLinkedList = new OrderLinkedList();
        orderLinkedList.delete(2);
        orderLinkedList.insert(1);
        orderLinkedList.insert(2);
        orderLinkedList.insert(3);
        orderLinkedList.display();
        orderLinkedList.delete(2);
        orderLinkedList.display();
        orderLinkedList.delete(10);
        orderLinkedList.display();
    }

    /**
     * 测试根据data值查找节点
     */
    @Test
    public void testFind() {
        OrderLinkedList orderLinkedList = new OrderLinkedList();
        orderLinkedList.find(3);
        orderLinkedList.insert(1);
        orderLinkedList.insert(2);
        orderLinkedList.insert(3);
        orderLinkedList.display();
        boolean flag = orderLinkedList.find(3);
        System.out.println(flag);
        flag = orderLinkedList.find(5);
        System.out.println(flag);
    }
}

6 单向循环链表

单链表是不闭合的,单向循环链表尾节点的next指针指向头节点,形成闭环。

6.1 代码示例
package com.example.array;

/**
 * 单向循环链表
 */
public class CircleLinkedList {

    /**
     * 元素个数
     */
    private int size;
    /**
     * 头节点
     */
    private Node head;

    private class Node {

        /**
         * 数据
         */
        private int data;
        /**
         * 下一个节点
         */
        private Node next;

        public Node(int data) {
            this.data = data;
        }
    }

    /**
     * 添加节点
     * @param data
     * @return
     */
    public boolean insert(int data) {
        Node newNode = new Node(data);
        if (isEmpty()) {
            newNode.next = newNode;
            head = newNode;
        } else {
            Node current = head;
            while (true) {
                if (current.next == head) {
                    newNode.next = head;
                    current.next = newNode;
                    break;
                }
                current = current.next;
            }
        }
        size++;
        return true;
    }

    /**
     * 根据data值删除节点
     * @param data
     * @return
     */
    public boolean delete(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值删除节点!");
            return false;
        }
        if (head.next == head) {
            head = null;
        } else {
            Node current = head;
            Node previous = head;
            while (true) {
                if (current.next == head) {
                    previous = current;
                    current = head;
                    break;
                }
                current = current.next;
            }
            while (current.data != data) {
                if (current.next == head) {
                    System.out.println("根据data值未找到节点,无法根据data值删除节点!");
                    return false;
                } else {
                    previous = current;
                    current = current.next;
                }
            }
            if (current == head) {
                head = current.next;
                current.next = null;
                previous.next = head;
            } else if (current.next == head) {
                current.next = null;
                previous.next = head;
            } else {
                previous.next = current.next;
                current.next = null;
            }
        }
        size--;
        return true;
    }

    /**
     * 根据data值查找节点
     * @param data
     * @return
     */
    public boolean find(int data) {
        if (isEmpty()) {
            System.out.println("链表为空,无法根据data值查找节点!");
            return false;
        }
        Node current = head;
        int tempSise = size;
        while (tempSise > 0) {
            if (data == current.data) {
                return true;
            } else {
                current = current.next;
            }
            tempSise--;
        }
        return false;
    }

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

    /**
     * 获取链表元素个数
     * @return
     */
    public int getSize() {
        return size;
    }

    /**
     * 遍历链表
     */
    public void display() {
        if (isEmpty()) {
            System.out.println("遍历结果:链表为空!");
            return;
        }
        if (size == 1) {
            System.out.println("遍历结果:" + head.data);
            return;
        }
        Node node = head;
        int tempSize = size;
        System.out.print("遍历结果:");
        while (tempSize > 0) {
            System.out.print(node.data + "\t");
            node = node.next;
            tempSize--;
        }
        System.out.println();
    }
}
6.2 测试
package com.example.array;

import org.junit.Test;

/**
 * 测试单向链表
 */
public class TestCircleLinkedList {

    /**
     * 测试添加节点
     */
    @Test
    public void testInsert() {
        CircleLinkedList circleLinkedList = new CircleLinkedList();
        circleLinkedList.insert(1);
        circleLinkedList.display();
        circleLinkedList.insert(2);
        circleLinkedList.display();
    }

    /**
     * 测试根据data值删除节点
     */
    @Test
    public void testDelete() {
        CircleLinkedList circleLinkedList = new CircleLinkedList();
        circleLinkedList.delete(2);
        circleLinkedList.insert(1);
        circleLinkedList.insert(2);
        circleLinkedList.insert(3);
        circleLinkedList.display();
        circleLinkedList.delete(2);
        circleLinkedList.display();
        circleLinkedList.delete(10);
        circleLinkedList.display();
        circleLinkedList.delete(3);
        circleLinkedList.display();
        circleLinkedList.delete(1);
        circleLinkedList.display();
    }

    /**
     * 测试根据data值查找节点
     */
    @Test
    public void testFind() {
        CircleLinkedList circleLinkedList = new CircleLinkedList();
        circleLinkedList.find(3);
        circleLinkedList.insert(1);
        circleLinkedList.insert(2);
        circleLinkedList.insert(3);
        circleLinkedList.display();
        boolean flag = circleLinkedList.find(3);
        System.out.println(flag);
        flag = circleLinkedList.find(5);
        System.out.println(flag);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值