链表:自定义单链表总结

本文介绍了一种自定义单链表的Java实现方法,包括基本操作如获取首尾元素、添加与删除节点、链表反转等功能,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单链表实现

主要实现有:

1 获取首尾元素

2 是否包含某元素

3.1 尾部添加

3.2 头部添加

3.3 某节点后插入

3.4 某节点前插入

4.1 尾部删除

4.2 头部删除

4.3 某节点后删除

5 删除第k个元素

6 删除元素值为key的所有节点

7 链表反转(逆置)

8 获取k 位置上的节点

9 迭代器的实现

Java实现

package com.base;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 自定义单链表各功能的实现
 * 
 * @author Administrator
 *
 * @param <Item>
 */
public class LinkedList<Item> implements Iterable<Item> {
    // 单链表结点
    private class Node {
        private Item item;
        private Node next;
    }

    private Node first; // 头指针
    private Node last; // 末尾指针
    private int N;

    public LinkedList() {
        first = null;
        last = null;
    }

    public LinkedList(Item[] a) {
        for (Item i : a)
            append(i); // 追加
    }

    public LinkedList(Iterable<Item> coll) {
        for (Item i : coll)
            append(i);
    }

    public boolean isEmpty() {
        return first == null;
    }

    public int size() {
        return N;
    }

    /**
     * 返回头尾节点元素
     * 
     * @return
     */
    public Item first() {
        if (isEmpty())
            throw new RuntimeException("链表为空");
        return first.item;
    }

    public Item last() {
        if (isEmpty())
            throw new RuntimeException("链表为空");
        return last.item;
    }

    /**
     * 是否含有某元素
     * 
     * @param item
     * @return
     */
    public boolean contains(Item item) {
        Node curr = first;
        while (curr != null && !curr.item.equals(item))
            curr = curr.next;
        return curr != null;
    }

    /**
     * 末尾追加
     * 
     * @param item
     */
    public void append(Item item) {
        Node oldLast = last;
        Node last = new Node();
        last.item = item;
        last.next = null;
        if (isEmpty())
            first = last;
        else
            oldLast.next = last;
        N++;
    }

    /**
     * 头部添加
     * 
     * @param item
     */
    public void prepend(Item item) {
        Node x = new Node();
        x.item = item;
        if (isEmpty()) {
            first = x;
            last = x;
        } else {
            x.next = first;
            first = x;
        }
        N++;
    }

    /**
     * 某节点后插入
     */
    public void insertAfter(Node a, Node b) {
        if (a != null && b != null) {
            if (last == a)
                last = b; // 如果是最后一个指定好last指针的位置
            b.next = a.next;
            a.next = b;
            N++;
        }
    }

    /**
     * 某节点之前插入节点
     */
    public void insertBefore(Node a, Node b) {
        if (a != null && b != null) {
            if (first == a) {
                b.next = a;
                first = b;
            } else {
                Node prev = null, curr = first;
                while (curr.next != null) {
                    if (curr.next == a) {
                        prev = curr.next;
                        prev.next = b;
                        b.next = a;
                        break;
                    }
                }
            }
            N++;
        }
    }

    /**
     * 尾部删除
     * 
     * @return
     */
    public Item removeLast() {
        if (isEmpty())
            throw new RuntimeException("链表为空");
        if (first == last) {
            Item item = first.item;
            first = last = null;
            N--;
            return item;
        }
        //
        Item item = last.item;
        Node prev = null, curr = first;
        while (curr.next != null) {
            prev = curr;
            curr = curr.next;
        }
        prev.next = null;
        last = prev;
        N--;
        return item;
    }

    /**
     * 头部删除
     */
    public Item removeFirst() {
        if (isEmpty())
            throw new RuntimeException("链表为空");
        Item item = first.item;
        first = first.next;
        N--;
        if (isEmpty())
            last = null;
        return item;
    }

    /**
     * 某节点后删除
     */
    public void removeAfter(Node node) {
        if (node != null && node.next != null) {
            if (node.next.next == null)
                last = node; // last指针位置
            node.next = node.next.next;
            N--;
        }
    }

    /**
     * 某节点前删除
     */
    // TODO
    /**
     * 删除第k个元素
     */
    public Item delete(int k) {
        if (k < 1)
            return null;
        int i = 1;
        Node prev = null, curr = first;
        while (i < k && curr != null) { // 找到第k个元素
            prev = curr;
            curr = curr.next;
            i++;
        }
        if (curr != null) {
            if (prev == null)
                first = curr.next;
            else
                prev.next = curr.next;
            if (curr.next == null)
                last = prev;
            N--;
            return curr.item;
        } else
            return null;
    }

    /**
     * 链表反转
     * 
     * 思想:将原链表的节点一个一个拆下来放到新的链表头部
     */
    public void reverse() {
        first = reverse(first);
        setLastAndN(); // 设置last指针的位置和N的数目
    }

    public Node reverse(Node node) {
        Node srcFirst = node;
        Node destFirst = null;
        while (srcFirst != null) {
            Node next = srcFirst.next;
            srcFirst.next = destFirst;
            destFirst = srcFirst;
            srcFirst = next;
        }
        return destFirst;
    }

    public void setLastAndN() { // 设置last指针的位置和N的数目
        last = first;
        N = 0;
        if (first != null) {
            N++;
            while (last.next != null) {
                last = last.next;
                N++;
            }
        }
    }

    /**
     * 删除Item 为key的所有结点
     * 
     * 思想:首先找到item为key的节点的位置
     */
    public void remove(Item item) {
        LinkedList<Integer> idx = new LinkedList<>(); // 声明链表
        int i = 1;
        for (Item x : this) {
            if (x.equals(item))
                idx.prepend(i);
            i++;
        }
        for (int k : idx)
            delete(k);
    }

    /**
     * 获取k位置上的节点
     */
    public Node node(int k) {
        if (k < 1)
            return null;
        int i = 1;
        Node curr = first;

        while (i < k && curr != null) {
            curr = curr.next;
            i++;
        }
        return curr;
    }

    /**
     * 迭代器
     */
    @Override
    public Iterator<Item> iterator() {

        return new ListIterator();
    }

    private class ListIterator implements Iterator<Item> {
        private Node current = first;

        @Override
        public boolean hasNext() {
            return current != null;
        }

        @Override
        public Item next() {
            if (!hasNext())
                throw new NoSuchElementException();
            Item item = current.item;
            current = current.next;
            return item;
        }

        @Override
        public void remove() {
            throw new UnsupportedOperationException();
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值