数据结构-单向链表实现

从上海到北京的高铁一路可能要经过苏州/无锡/常州/济南/天津/北京,如果将每个连接使用一个指向连接起来,可以形成一个链,这样就可以知道某个站的下一个站是哪个。

单向链表

每个站点抽象为一个节点,在每个节点中记录下一个站的名称,从而串成链条,这样的数据结构称为单向链表。其中指向称为指针域,指针域指向的节点称为后继节点。

单向链表

Class SingleLinkedList<E>

属性概述

作用域和类型 属性和描述 备注
private final Node head
标识链表头位置
该属性默认一个空值节点,前驱为空,后驱为链表第一个有效节点
private int size
记录链表长度
添加节点 +1 删除节点 -1
static final class Node
内部节点类
拥有 next 指针域和 data 数据域

方法概述

作用域和类型 函数和描述 备注
public void add(E data)
添加新值到链表
该节点在链表末尾添加
public Object delete(int index)
删除指定位置节点且返回节点
遍历到 index 位置删除
public void insert(int index, E data)
添加新值到链表指定位置
遍历到 index 位置删除
public int getSize()
获取链表的长度
返回属性 size 当前值
public Object getData(int index)
获取链表指定位置的值
public void print()
打印链表
用于调试
public boolean isEmpty()
判断链表为空
public void clear() clear()
清空链表数据部分
保留了头部节点

关键操作步骤

链表末尾添加元素

链表末尾添加元素,一般使用遍历方法寻找到最后一个节点,默认最有一个节点的 next 指向为空

第一步:使用遍历方法寻找到最后一个节点 lastNode ;
第二步:将 lastNode 的 next 指针域指向 newNode;将 newNode 作为 lastNode 的下一个节点;

链表末尾添加元素

public void add(E data) {
    Node newNode = new Node(data);
    Node lastNode = head;
    while (lastNode.next != null) {
        lastNode = lastNode.next;
    }
    lastNode.next = newNode;
    size++;
}

删除指定下标的元素

删除指定下标的元素,采用遍历寻找方式找到指定下标元素的前一个节点,将该节点和删除节点的指向切断直接指向删除节点的下一个节点。

第一步:使用遍历方法寻找到最后一个节点 preNode ;
第二步:获取 preNode 的下一个节点即 delNode ;
第三步:获取 preNode 的下一个节点直接指向 delNode的下一个节点 ;

删除指定下标的元素


public Object delete(int index) {
    Node preNode = head;
    if (index > getSize()) return null;
    for (int i = 1; i < index; i++) {
        preNode = preNode.next;
    }
    Node delNode = preNode.next;
    preNode.next = delNode.next;
    size--;
    return delNode;
}

向指定下标的添加元素

向指定下标的添加元素,采用遍历方式寻找该下标对应的节点的上一个节点 prevNode,在 prevNode 和其后继节点 successorNode 之间插入 newNode。步骤如下:

第一步:获取该删除节点的后继节点 successorNode;
第二步:将 prevNode 的 next 指针域指向 newNode;
第三步:将 newNode 的 next 指针域指向 successorNode;

向指定下标的添加元素


public void insert(int index, E data) {
    Node newNode = new Node(data);
    Node preNode = head;
    if (index > getSize()) return;
    for (int i = 1; i < index; i++) {
        preNode = preNode.next;
    }
    Node successor = preNode.next;
    preNode.next = newNode;
    newNode.next = successor;
    size++;
}

编码实现

interface LinkedList<E>

package com.skystep.数据结构和算法.链表.双向链表;

public interface LinkedList<E> {
    //在链表尾部增加数据
    void add(E data);

    //删除指定位置的节点
    Object delete(int index);

    //在指定索引处插入节点
    void insert(int index, E data);

    //获取链表长度;
    int getSize();

    //获取某个索引数据
    Object getData(int index);

    void print();

    //是否空
    boolean isEmpty();

    // 清空链表
    void clear();

}

class SingleLinkedList<E>

package com.skystep.数据结构和算法.链表.单向链表;

public class SingleLinkedList<E> implements LinkedList<E> {

    Node head = new Node();
    int size = 0;

    static final class Node<E> {
        private Node next = null;
        private E data = null;

        public Node() {
        }

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

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

        public Node getNext() {
            return next;
        }

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

        public E getData() {
            return data;
        }

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

    @Override
    public void add(E data) {
        Node newNode = new Node(data);
        Node lastNode = head;
        while (lastNode.next != null) {
            lastNode = lastNode.next;
        }
        lastNode.next = newNode;
        size++;
    }

    @Override
    public Object delete(int index) {
        Node preNode = head;
        if (index > getSize()) return null;
        for (int i = 1; i < index; i++) {
            preNode = preNode.next;
        }
        Node delNode = preNode.next;
        preNode.next = delNode.next;
        size--;
        return delNode;
    }

    @Override
    public void insert(int index, E data) {
        Node newNode = new Node(data);
        Node preNode = head;
        if (index > getSize()) return;
        for (int i = 1; i < index; i++) {
            preNode = preNode.next;
        }
        Node successor = preNode.next;
        preNode.next = newNode;
        newNode.next = successor;
        size++;
    }

    @Override
    public int getSize() {
        return size;
    }

    @Override
    public Object getData(int index) {
        Node temp = head;
        if (index > getSize()) return null;

        for (int i = 0; i < index; i++) {
            temp = temp.next;
        }
        return temp.data;
    }

    @Override
    public void print() {
        Node temp = head.next;
        while (temp != null) {
            System.out.print(temp.data + " ");
            temp = temp.next;
        }
    }

    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    @Override
    public void clear() {
        head.next = null;
        size = 0;
    }
}

class Client

package com.skystep.数据结构和算法.链表.单向链表;

public class Client {
    public static void main(String[] args) {
        LinkedList<Integer> singleLinkedList = new SingleLinkedList<>();
        singleLinkedList.add(1);
        singleLinkedList.add(2);
        singleLinkedList.add(3);
        singleLinkedList.insert(3, 10);
        System.out.println("size:" + singleLinkedList.getSize());
        singleLinkedList.print();
        System.out.println();
        System.out.println("第3个的值是:" + singleLinkedList.getData(3));
        singleLinkedList.delete(4);
        System.out.println("size:" + singleLinkedList.getSize());
        singleLinkedList.print();
        System.out.println();
        System.out.println("第2个的值是:" + singleLinkedList.getData(2));
        singleLinkedList.clear();
        System.out.println("size:" + singleLinkedList.getSize());
        singleLinkedList.print();
    }
}
posted @ 2021-11-30 18:19  yaomianwei  阅读(20)  评论(0编辑  收藏  举报