Java实现单链表的基本操作

本文详细介绍了如何使用Java实现单链表的基本操作,包括头插法和尾插法添加节点、在指定位置插入和删除节点、更新节点值、遍历链表、反转链表以及找到倒数第k个节点。通过示例代码展示了这些操作的实现过程,并进行了测试验证。
摘要由CSDN通过智能技术生成

      使用Java语言实现单链表的基本操作,包括对单链表的指定节点插入数据、删除指定位置节点的数据、修改指定节点的数据,查询数据;以及单链表的反转和倒数第k个节点的输出。

       线性表的链式存储结构:n个结点链结成一个链表,即为线性表的链式存储结构,由于每一个结点只包含一个指针域,因此称为单链表。
   链表中第一个结点的存储位置成为头指针,那么整个链表的存取就必须是从头指针开始了。有时候会在单链表的第一个结点前附设一个结点,称为头结点。

简单节点类,存储数据:Node.java

public class Node {
    int value; //数据域
    Node next; //指针域

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

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

}

模拟单链表类:SingleList.java

//单链表
public class SingleList {
    //头结点
    public Node head;

    //获取链表的长度的方法
    public int getLength() {
        int length = 0;
        Node cur = head;
        while (cur != null) {
            cur = cur.next;
            length++;
        }
        return length;
    }

    //   头插法,添加结点至链表头部
    public void addHeadNode(int value) {
        Node newNode = new Node(value);
        //头结点不存在,新结点成为头结点
        if (head == null) {
            head = newNode;
            return;
        }
        //新结点next直接指向当前头结点
        newNode.next = head;
        //新结点成为新的头结点
        head = newNode;
    }

    //   尾插法,添加结点至链表尾部
    public void addTailNode(int value) {
        Node newNode = new Node(value);
        //头结点不存在,新结点成为头结点
        if (head == null) {
            head = newNode;
            return;
        }
        //找到最后一个结点
        Node last = head;
        while (last.next != null) {
            last = last.next;
        }
        //新结点插入到链表尾部
        last.next = newNode;
    }

//     结点插入至指定位置

    public void addByIndex(int value, int index) {
        if (index < 0 || index > getLength()) { //注意index是可以等于size()的
            throw new IndexOutOfBoundsException("IndexOutOfBoundsException");
        }
        if (index == 0) {  //插入到头部
            addHeadNode(value);
        } else if (index == getLength()) {  //插入到尾部
            addTailNode(value);
        } else {  //插到某个中间位置
            Node newNode = new Node(value);
            int position = 0;
            Node cur = head;  //标记当前结点
            Node pre = null;  //记录前置结点
            while (cur != null) {
                if (position == index) {
                    newNode.next = cur;
                    pre.next = newNode;
                    return;
                }
                pre = cur;
                cur = cur.next;
                position++;
            }
        }
    }

//    删除指定位置的结点

    public void deleteByIndex(int index) {
        if (index < 0 || index > getLength() - 1) {
            throw new IndexOutOfBoundsException("IndexOutOfBoundsException");
        }
        if (index == 0) { //删除头
            head = head.next;
            return;
        }
        int position = 0;  //记录当前位置
        Node cur = head;  //标记当前结点
        Node pre = null;  //记录前置结点
        while (cur != null) {
            if (position == index) {
                pre.next = cur.next;
                cur.next = null;  //断开cur与链表的连接
                return;
            }
            pre = cur;
            cur = cur.next;
            position++;
        }

    }

    //修改操作
    public void update(int value, int index) {
        if (index < 0 || index > getLength() - 1) {
            throw new IndexOutOfBoundsException("IndexOutOfBoundsException");
        }
        int position = 0;
        Node cur = head;
        while (cur != null) {
            if (position == index) {
                cur.value = value;
            }
            cur = cur.next;
            position++;
        }
    }

    //遍历链表
    public void show() {
        Node cur = head;
        while (cur != null) {
            System.out.println(cur);
            cur = cur.next;
        }
    }

    //     链表反转
    public void reverse() {
        Node cur = head; //标记当前结点
        Node pre = null; //标记当前结点的前一个结点
        Node temp;
        while (cur != null) {
            //保存当前结点的下一个结点
            temp = cur.next;
            //cur.next指向pre,指针顺序置换
            cur.next = pre;
            //pre、cur继续后移
            pre = cur;
            cur = temp;
        }
        //最后一个结点变成新的头结点
        head = pre;
    }

    //   输出倒数第k个结点【新浪面试题】
    public Node getLastK(int k) {
        if (k < 0 || k > getLength()) {
            throw new IndexOutOfBoundsException("IndexOutOfBoundsException");
        }
        Node cur = head;
        for (int i = 1; i < getLength() - k + 1; i++) {
            cur = cur.next;
        }
        return cur;
    }

}

测试方法

 public static void main(String[] args) {
        SingleList list = new SingleList();
        list.addHeadNode(3);
        list.addHeadNode(2);
        list.addHeadNode(1);
        list.addTailNode(7);
        list.addTailNode(9);
        list.addByIndex(5, 1);
        list.show();
        System.out.println("倒数第2个节点:" + list.getLastK(2));
        System.out.println("-----------------------");
        //删除
        list.deleteByIndex(4);
        list.reverse();//翻转
        list.update(100, 1);
        list.show();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值