线性结构:链表


项目地址:https://gitee.com/caochenlei/data-structures

第一章 单向链表介绍

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

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

第二章 单向链表实现

2.01、初始化链表的结构

/**
 * 单向链表实现代码
 */
public class SinglyLinkedList<E> {
    
    
    //定义结点类
    public class Node {
    
    
        E data;     //代表结点数据
        Node next;  //指向下个结点

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

        @Override
        public String toString() {
    
    
            return "Node{data=" + data + "}";
        }
    }

    private Node head;  //代表链表头部
    private Node last;  //代表链表尾部
    private int size;   //代表链表长度

    public SinglyLinkedList() {
    
    
        this.head = new Node(null);
        this.last = null;
        this.size = 0;
    }

    //请将接下来的方法书写在这里...
}

2.02、判断链表是否为空

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

2.03、获取当前链表长度

//获取当前链表长度
public int size() {
    
    
    return size;
}

2.04、连接链表两个结点

//连接链表两个结点
public void connectNode(Node prevNode, Node nextNode) {
    
    
    if (prevNode != null) {
    
    
        prevNode.next = nextNode;
    }
}

2.05、释放链表结点指向

//释放链表结点指向
public void releaseNode(Node node) {
    
    
    if (node != null) {
    
    
        node.data = null;
        node.next = null;
    }
}

2.06、返回链表最后结点

//返回链表最后结点
public Node getLast() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return null;
    }
    //返回链表最后数据
    return last;
}

2.07、返回链表首个结点

//返回链表首个结点
public Node getFirst() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return null;
    }
    //返回链表首个数据
    return head.next;
}

2.08、返回指定位置结点

//返回指定位置结点
public Node getIndex(int index) {
    
    
    //判断位置是否违法
    if (index <= 0 || size < index) {
    
    
        throw new RuntimeException("链表位置不合法!");
    }
    //获取指定位置结点
    Node curNode = head;
    for (int i = 0; i < index; i++) {
    
    
        curNode = curNode.next;
    }
    //返回指定位置数据
    return curNode;
}

2.09、链表尾后添加数据

方法实现:

//链表尾后添加数据
public void addLast(E e) {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        //直接往head结点后插入
        last = new Node(e);
        connectNode(head, last);
    } else {
    
    
        //直接往last结点后插入
        Node oldLast = last;
        last = new Node(e);
        connectNode(oldLast, last);
    }
    //链表长度加一
    size++;
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

2.10、链表头后添加数据

方法实现:

//链表头后添加数据
public void addFirst(E e) {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        //直接往head结点后插入
        last = new Node(e);
        connectNode(head, last);
    } else {
    
    
        //获取首个结点
        Node firNode = head.next;
        //创建新的结点
        Node newNode = new Node(e);
        //两两结点连接
        connectNode(head, newNode);
        connectNode(newNode, firNode);
    }
    //链表长度加一
    size++;
}

方法测试:

扫描二维码关注公众号,回复: 12703126 查看本文章
public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addFirst("张三");
        linkedList.addFirst("李四");
        linkedList.addFirst("王五");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

2.11、指定位置添加数据

方法实现:

//指定位置添加数据
public void addIndex(int index, E e) {
    
    
    //寻找位置之前结点
    Node preNode = getIndexPreNode(index);
    //获取指定位置结点
    Node curNode = preNode.next;
    //创建一个新的结点
    Node newNode = new Node(e);
    //开始两两结点连接
    connectNode(preNode, newNode);
    connectNode(newNode, curNode);
    //当前链表长度加一
    size++;
}

//返回位置之前结点
private Node getIndexPreNode(int index) {
    
    
    //判断位置是否违法
    if (index <= 0 || size < index) {
    
    
        throw new RuntimeException("链表位置不合法!");
    }
    //寻找位置之前结点
    Node preNode = head;
    for (int i = 0; i < index - 1; i++) {
    
    
        preNode = preNode.next;
    }
    //返回位置之前结点
    return preNode;
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.addIndex(1, "小二");
        linkedList.addIndex(4, "老六");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=小二}
Node{data=张三}
Node{data=李四}
Node{data=老六}
Node{data=王五}
===============
false
5

2.12、删除指定位置结点

方法实现:

//删除指定位置结点
public void removeIndex(int index) {
    
    
    //寻找位置之前结点
    Node preNode = getIndexPreNode(index);
    //获取指定位置结点
    Node curNode = preNode.next;
    //删除指定位置结点
    preNode.next = curNode.next;
    //释放当前结点指向
    releaseNode(curNode);
    //链表长度大小减一
    size--;
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeIndex(2);

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=王五}
===============
false
2

2.13、删除链表首个结点

方法实现:

//删除链表首个结点
public void removeFirst() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //删除首个结点
    removeIndex(1);
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeFirst();
        linkedList.removeFirst();

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
===============
false
1

2.14、删除链表最后结点

方法实现:

//删除链表最后结点
public void removeLast() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //删除最后结点
    removeIndex(size);
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeLast();
        linkedList.removeLast();

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
===============
false
1

2.15、顺序输出链表内容

方法实现:

//顺序输出链表内容
public void show() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //获取首个结点
    Node curNode = head.next;
    //循环往后移动
    while (curNode != null) {
    
    
        System.out.println(curNode);
        curNode = curNode.next;
    }
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");


        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

2.16、逆序输出链表内容

方法实现:

//逆序输出链表内容
public void reverseShow() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //递归倒序打印
    reverseShow(head.next);
}

private void reverseShow(Node node) {
    
    
    //判断是否结束
    if (node == null) {
    
    
        return;
    }
    //递归调用函数
    reverseShow(node.next);
    //打印当前结点
    System.out.println(node);
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println("===============");
        linkedList.reverseShow();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

2.17、首尾反转当前链表

方法实现:

//首尾反转当前链表
public void reverse() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //创建一个新头
    Node newHead = new Node(null);
    //获取首个结点
    Node curNode = head.next;
    //定义临时结点
    Node tmpNode;
    //循环遍历链表
    while (curNode != null) {
    
    
        //缓存当前结点下个结点
        tmpNode = curNode.next;
        //获取链表新头首个结点
        Node firNode = newHead.next;
        //开始结点两两连接关联
        connectNode(newHead, curNode);
        connectNode(curNode, firNode);
        //让当前的结点往后移动
        curNode = tmpNode;
    }
    //老头换首结点
    head.next = newHead.next;
    //释放新头指向
    releaseNode(newHead);
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.reverse();

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

2.18、清空链表所有结点

方法实现:

//清空链表所有结点
public void clear() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //定义当前结点
    Node curNode = head;
    //定义临时结点
    Node tmpNode;
    //重置基本变量
    head = null;
    last = null;
    size = 0;
    //循环释放结点
    while (curNode != null) {
    
    
        //缓存下个结点
        tmpNode = curNode.next;
        //释放当前结点
        releaseNode(curNode);
        //移动下个结点
        curNode = tmpNode;
    }
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.clear();

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
===============
true
0

2.19、顺序查找数据首次出现位置

方法实现:

//顺序查找数据首次出现位置
public int indexOf(E e) {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return -1;
    }
    //判断对象是否为空
    if (e == null) {
    
    
        return -1;
    }
    //获取指定位置结点
    Node curNode = head;
    for (int i = 0; curNode != null; i++) {
    
    
        if (e.equals(curNode.data)) {
    
    
            return i;
        }
        curNode = curNode.next;
    }
    //没有找到返回负一
    return -1;
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println(linkedList.indexOf("王五"));

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

3
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

2.20、逆序查找数据首次出现位置

方法实现:

//逆序查找数据首次出现位置
public int lastIndexOf(E e) {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return -1;
    }
    //判断对象是否为空
    if (e == null) {
    
    
        return -1;
    }
    //反转当前链表结点
    reverse();
    //获取指定位置结点
    int index = indexOf(e);
    //反转当前链表结点
    reverse();
    //返回指定位置结果
    return index;
}

方法测试:

public class SinglyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        SinglyLinkedList<String> linkedList = new SinglyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println(linkedList.lastIndexOf("王五"));

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

1
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

第三章 双向链表介绍

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。链表的头结点的数据域不存储数据,指向前驱结点的指针域值为null,指向后继结点的指针域指向第一个真正存储数据结点。

第四章 双向链表实现

4.01、初始化链表的结构

/**
 * 双向链表实现代码
 */
public class DoublyLinkedList<E> {
    
    
    //定义结点类
    public class Node {
    
    
        Node prev;  //指向上个结点
        E data;     //代表结点数据
        Node next;  //指向下个结点

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

        @Override
        public String toString() {
    
    
            return "Node{data=" + data + "}";
        }
    }

    private Node head;  //代表链表头部
    private Node last;  //代表链表尾部
    private int size;   //代表链表长度

    public DoublyLinkedList() {
    
    
        this.head = new Node(null);
        this.last = null;
        this.size = 0;
    }
    
    //请将接下来的方法书写在这里...
}

4.02、判断链表是否为空

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

4.03、获取当前链表长度

//获取当前链表长度
public int size() {
    
    
    return size;
}

4.04、连接链表两个结点

//连接链表两个结点
public void connectNode(Node prevNode, Node nextNode) {
    
    
    if (prevNode != null) {
    
    
        prevNode.next = nextNode;
    }
    if (nextNode != null) {
    
    
        nextNode.prev = prevNode;
    }
}

4.05、释放链表结点指向

//释放链表结点指向
public void releaseNode(Node node) {
    
    
    if (node != null) {
    
    
        node.prev = null;
        node.data = null;
        node.next = null;
    }
}

4.06、返回链表最后结点

//返回链表最后结点
public Node getLast() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return null;
    }
    //返回链表最后数据
    return last;
}

4.07、返回链表首个结点

//返回链表首个结点
public Node getFirst() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return null;
    }
    //返回链表首个数据
    return head.next;
}

4.08、返回指定位置结点

//返回指定位置结点
public Node getIndex(int index) {
    
    
    //判断位置是否违法
    if (index <= 0 || size < index) {
    
    
        throw new RuntimeException("链表位置不合法!");
    }
    //获取指定位置结点
    Node curNode = head;
    for (int i = 0; i < index; i++) {
    
    
        curNode = curNode.next;
    }
    //返回指定位置数据
    return curNode;
}

4.09、链表尾后添加数据

方法实现:

//链表尾后添加数据
public void addLast(E e) {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        //直接往head结点后插入
        last = new Node(e);
        connectNode(head, last);
    } else {
    
    
        //直接往last结点后插入
        Node oldLast = last;
        last = new Node(e);
        connectNode(oldLast, last);
    }
    //链表长度加一
    size++;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

4.10、链表头后添加数据

方法实现:

//链表头后添加数据
public void addFirst(E e) {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        //直接往head结点后插入
        last = new Node(e);
        connectNode(head, last);
    } else {
    
    
        //获取首个结点
        Node firNode = head.next;
        //创建新的结点
        Node newNode = new Node(e);
        //两两结点连接
        connectNode(head, newNode);
        connectNode(newNode, firNode);
    }
    //链表长度加一
    size++;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addFirst("张三");
        linkedList.addFirst("李四");
        linkedList.addFirst("王五");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

4.11、指定位置添加数据

方法实现:

//指定位置添加数据
public void addIndex(int index, E e) {
    
    
    //获取指定位置结点
    Node curNode = getIndex(index);
    //指定位置前个结点
    Node prevNode = curNode.prev;
    //创建一个新的结点
    Node newNode = new Node(e);
    //开始两两结点连接
    connectNode(prevNode, newNode);
    connectNode(newNode, curNode);
    //当前链表长度加一
    size++;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.addIndex(1, "小二");
        linkedList.addIndex(4, "老六");

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=小二}
Node{data=张三}
Node{data=李四}
Node{data=老六}
Node{data=王五}
===============
false
5

4.12、删除链表最后结点

方法实现:

//删除链表最后结点
public void removeLast() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return;
    }
    //获取链表最后节点
    Node lastNode = last;
    //删除链表最后结点
    Node prevNode = lastNode.prev;
    prevNode.next = null;
    //释放最后节点指向
    releaseNode(lastNode);
    //修改last的指向
    last = prevNode;
    //让链表的长度减一
    size--;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeLast();
        linkedList.removeLast();

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
===============
false
1

4.13、删除链表首个结点

方法实现:

//删除链表首个结点
public void removeFirst() {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return;
    }
    //获取链表首个结点
    Node firsNode = head.next;
    //删除链表首个结点
    Node nextNode = firsNode.next;
    connectNode(head, nextNode);
    //释放首个结点指向
    releaseNode(firsNode);
    //修改last的指向
    last = nextNode;
    //让链表的长度减一
    size--;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeFirst();
        linkedList.removeFirst();

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
===============
false
1

4.14、删除指定位置结点

方法实现:

//删除指定位置结点
public void removeIndex(int index) {
    
    
    //获取指定位置结点
    Node curNode = getIndex(index);
    //指定位置前个结点
    Node prevNode = curNode.prev;
    //指定位置后个结点
    Node nextNode = curNode.next;
    //开始两两结点连接
    connectNode(prevNode, nextNode);
    //释放当前结点指向
    releaseNode(curNode);
    //当前链表长度减一
    size--;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.removeIndex(2);

        System.out.println("===============");
        for (int i = 0; i < linkedList.size(); i++) {
    
    
            System.out.println(linkedList.getIndex(i + 1));
        }
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=王五}
===============
false
2

4.15、顺序输出链表内容

方法实现:

//顺序输出链表内容
public void show() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //获取首个结点
    Node curNode = head.next;
    //循环往后移动
    while (curNode != null) {
    
    
        System.out.println(curNode);
        curNode = curNode.next;
    }
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");


        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

4.16、逆序输出链表内容

方法实现:

//逆序输出链表内容
public void reverseShow() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //获取最后结点
    Node curNode = last;
    //循环往前移动
    while (curNode.prev != null) {
    
    
        System.out.println(curNode);
        curNode = curNode.prev;
    }
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println("===============");
        linkedList.reverseShow();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

4.17、首尾反转当前链表

方法实现:

//首尾反转当前链表
public void reverse() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //创建一个新头
    Node newHead = new Node(null);
    //获取首个结点
    Node curNode = head.next;
    //定义临时结点
    Node tmpNode;
    //循环遍历链表
    while (curNode != null) {
    
    
        //缓存当前结点下个结点
        tmpNode = curNode.next;
        //获取链表新头首个结点
        Node firNode = newHead.next;
        //开始结点两两连接关联
        connectNode(newHead, curNode);
        connectNode(curNode, firNode);
        //让当前的结点往后移动
        curNode = tmpNode;
    }
    //老头换首结点
    head.next = newHead.next;
    //释放新头指向
    releaseNode(newHead);
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.reverse();

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
Node{data=王五}
Node{data=李四}
Node{data=张三}
===============
false
3

4.18、清空链表所有结点

方法实现:

//清空链表所有结点
public void clear() {
    
    
    //判断链表为空
    if (isEmpty()) {
    
    
        return;
    }
    //定义当前结点
    Node curNode = head;
    //定义临时结点
    Node tmpNode;
    //重置基本变量
    head = null;
    last = null;
    size = 0;
    //循环释放结点
    while (curNode != null) {
    
    
        //缓存下个结点
        tmpNode = curNode.next;
        //释放当前结点
        releaseNode(curNode);
        //移动下个结点
        curNode = tmpNode;
    }
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        linkedList.clear();

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

===============
===============
true
0

4.19、顺序查找数据首次出现位置

方法实现:

//顺序查找数据首次出现位置
public int indexOf(E e) {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return -1;
    }
    //判断对象是否为空
    if (e == null) {
    
    
        return -1;
    }
    //获取指定位置结点
    Node curNode = head;
    for (int i = 0; curNode != null; i++) {
    
    
        if (e.equals(curNode.data)) {
    
    
            return i;
        }
        curNode = curNode.next;
    }
    //没有找到返回负一
    return -1;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println(linkedList.indexOf("王五"));

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

3
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

4.20、逆序查找数据首次出现位置

方法实现:

//逆序查找数据首次出现位置
public int lastIndexOf(E e) {
    
    
    //判断链表是否为空
    if (isEmpty()) {
    
    
        return -1;
    }
    //判断对象是否为空
    if (e == null) {
    
    
        return -1;
    }
    //获取指定位置结点
    Node curNode = last;
    for (int i = 1; curNode != null; i++) {
    
    
        if (e.equals(curNode.data)) {
    
    
            return i;
        }
        curNode = curNode.prev;
    }
    //没有找到返回负一
    return -1;
}

方法测试:

public class DoublyLinkedListTest {
    
    
    public static void main(String[] args) {
    
    
        DoublyLinkedList<String> linkedList = new DoublyLinkedList<>();

        linkedList.addLast("张三");
        linkedList.addLast("李四");
        linkedList.addLast("王五");

        System.out.println(linkedList.lastIndexOf("王五"));

        System.out.println("===============");
        linkedList.show();
        System.out.println("===============");
        System.out.println(linkedList.isEmpty());
        System.out.println(linkedList.size());
    }
}

运行结果:

1
===============
Node{data=张三}
Node{data=李四}
Node{data=王五}
===============
false
3

猜你喜欢

转载自blog.csdn.net/qq_38490457/article/details/114409919