Java实现单向链表以及简单功能

最近在看数据结构,看到了链表.

单向链表每个节点都有一个指向下一个元素的指针,最后一个节点的后继节点为null表示链表的结束.

链表的遍历是从表头开始,直到下个节点为空结束遍历.

放一个toString方法,演示下遍历.

@Override
public String toString() {
    if (headerNode == null) {
        return "[]";
    } else {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        sb.append(headerNode.element);
        ListNode<E> firstNode = headerNode;
        ListNode<E> iterator = firstNode.next;
        while (iterator != null) {
            sb.append(",").append(iterator.element);
            iterator = iterator.next;
        }
        return sb.append("]").toString();
    }
}

链表的插入分为三种情况

  • 向表头插入节点

将新节点的后继节点指向原来的表头,然后将表头设置为新节点

 /**
  * 向表头增加元素
  * @param element 需要增加的元素
  */
 public void addFirst(E element) {
     ListNode<E> newFirstNode = new ListNode<>(element);
     newFirstNode.next = headerNode;
     headerNode = newFirstNode;
 }
  • 向指定位置插入节点

将新节点的后继节点更新为目标节点的后继节点,然后将目标节点的后继节点更新为新节点.

/**
 * 在指定元素后添加元素
 *
 * @param previousElement 先前的元素
 * @param newElement      插入的元素
 */
public void add(E previousElement, E newElement) {
    if (headerNode == null) {
        throw new RuntimeException("链表中没有元素");
    }
    ListNode<E> firstNode = headerNode;
    ListNode<E> targetNode = null;
    if (firstNode.element.equals(previousElement)) {
        targetNode = firstNode;
    }
    ListNode<E> iterator = firstNode.next;
    while (iterator != null) {
        if (iterator.element.equals(previousElement)) {
            targetNode = iterator;
            break;
        }
        iterator = iterator.next;
    }
    if (targetNode == null) {
        throw new RuntimeException("链表中无法查找到指定元素所处的位置");
    } else {
        ListNode<E> newListNode = new ListNode<>(newElement);
        newListNode.next = targetNode.next;
        targetNode.next = newListNode;
    }
}
  • 向表尾插入节点

将表尾节点的后继节点更新为新节点,新节点的后继节点为null.

/**
 * 向链表末尾添加元素
 *
 * @param element 需要添加的元素
 */
public void add(E element) {
    if (headerNode == null) {
        headerNode = new ListNode<>(element);
        return;
    }
    //获取首节点
    ListNode<E> firstNode = headerNode;
    //遍历到尾节点,并将新节点的地址(指针)赋值给next
    while (firstNode.next != null) {
        firstNode = firstNode.next;
    }
    firstNode.next = new ListNode<>(element);
}

删除也分三种情况

  • 删除表头

将表头元素的后继节点设置为新的表头,然后将原表头的后继节点设置为null

  • 删除中间的指定位置

将指定节点的前驱节点 指向后继节点.然后指定节点的后继节点设置为null

  • 删除表尾

将表尾的前驱节点的后继节点设置为null即可.

/**
 * 移除链表中的某个元素
 *
 * @param element 需要移除的元素
 */
public boolean remove(E element) {
    if (headerNode == null) {
        throw new RuntimeException("链表中没有元素");
    }
    ListNode<E> firstNode = headerNode;
    ListNode<E> iterator = firstNode.next;
    if (firstNode.element.equals(element)) {
        headerNode = iterator;
        firstNode.next = null;
        return true;
    }
    ListNode<E> preIterator = firstNode;
    while (iterator != null) {
        if (iterator.element.equals(element)) {
            preIterator.next = iterator.next;
            iterator.next = null;
            return true;
        }
        preIterator = iterator;
        iterator = iterator.next;
    }
    return false;
}

放个整体代码.

package com.relic.linkedlist;


/**
 * 单向链表的简单实现
 *
 * @author Relic
 */
public class MyLinkedList<E> {

    /**
     * 链表的表头节点
     */
    private ListNode<E> headerNode;

    public MyLinkedList(E element) {
        headerNode = new ListNode<>(element);
        headerNode.next = null;
    }

    public MyLinkedList() {
        headerNode = null;
    }

    public static void main(String[] args) {
        MyLinkedList<String> list = new MyLinkedList<>();
        list.add("test1");
        list.add("test2");
        list.add("test3");
        list.add("test2", "test4");
        list.addFirst("test0");
        System.out.println(list);
        System.out.println(list.indexOf(7));
        System.out.println(list.lastIndexOf(2));
        System.out.println(list.size());
        System.out.println(list.contains("test1"));
        System.out.println(list.remove("test3"));
        System.out.println(list);
    }

    /**
     * 向链表末尾添加元素
     *
     * @param element 需要添加的元素
     */
    public void add(E element) {
        if (headerNode == null) {
            headerNode = new ListNode<>(element);
            return;
        }
        //获取首节点
        ListNode<E> firstNode = headerNode;
        //遍历到尾节点,并将新节点的地址(指针)赋值给next
        while (firstNode.next != null) {
            firstNode = firstNode.next;
        }
        firstNode.next = new ListNode<>(element);
    }

    /**
     * 在指定元素后添加元素
     *
     * @param previousElement 先前的元素
     * @param newElement      插入的元素
     */
    public void add(E previousElement, E newElement) {
        if (headerNode == null) {
            throw new RuntimeException("链表中没有元素");
        }
        ListNode<E> firstNode = headerNode;
        ListNode<E> targetNode = null;
        if (firstNode.element.equals(previousElement)) {
            targetNode = firstNode;
        }
        ListNode<E> iterator = firstNode.next;
        while (iterator != null) {
            if (iterator.element.equals(previousElement)) {
                targetNode = iterator;
                break;
            }
            iterator = iterator.next;
        }
        if (targetNode == null) {
            throw new RuntimeException("链表中无法查找到指定元素所处的位置");
        } else {
            ListNode<E> newListNode = new ListNode<>(newElement);
            newListNode.next = targetNode.next;
            targetNode.next = newListNode;
        }
    }

    /**
     * 向表头增加元素
     *
     * @param element 需要增加的元素
     */
    public void addFirst(E element) {
        ListNode<E> newFirstNode = new ListNode<>(element);
        newFirstNode.next = headerNode;
        headerNode = newFirstNode;
    }

    /**
     * 移除链表中的某个元素
     *
     * @param element 需要移除的元素
     */
    public boolean remove(E element) {
        if (headerNode == null) {
            throw new RuntimeException("链表中没有元素");
        }
        ListNode<E> firstNode = headerNode;
        ListNode<E> iterator = firstNode.next;
        if (firstNode.element.equals(element)) {
            headerNode = iterator;
            firstNode.next = null;
            return true;
        }
        ListNode<E> preIterator = firstNode;
        while (iterator != null) {
            if (iterator.element.equals(element)) {
                preIterator.next = iterator.next;
                iterator.next = null;
                return true;
            }
            preIterator = iterator;
            iterator = iterator.next;
        }
        return false;
    }

    /**
     * 返回链表中是否包括某个元素
     *
     * @param element 查找的元素
     * @return 的布尔值
     */
    public boolean contains(E element) {
        ListNode<E> iterator = headerNode;
        do {
            if (iterator.element.equals(element)) {
                return true;
            }
            iterator = iterator.next;
        } while (iterator != null);
        return false;
    }

    /**
     * @return int 链表的长度
     */
    public int size() {
        int length = 0;
        ListNode<E> firstNode = headerNode;
        if (firstNode == null) {
            return 0;
        }
        ListNode<E> iterator = firstNode.next;
        while (iterator != null) {
            length++;
            iterator = iterator.next;
        }
        //加上首节点
        return length + 1;
    }

    /**
     * 根据角标返回链表中的元素
     *
     * @param index 链表中的位置
     * @return 指定的元素
     */
    public E indexOf(int index) {
        ListNode<E> iterator = headerNode;
        for (int i = 1; i < index; i++) {
            if (iterator.next == null) {
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
            }
            iterator = iterator.next;
        }
        return iterator.element;
    }

    /**
     * 返回从末尾开始计数指定角标的元素
     *
     * @param index 从末尾开始的位置
     * @return 指定的元素
     */
    public E lastIndexOf(int index) {
        ListNode<E> pre = headerNode;
        ListNode<E> later = headerNode;
        //pre指针先移动index个长度
        for (int i = 1; i < index; i++) {
            //超出链表长度,
            if (pre.next == null) {
                throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
            }
            pre = pre.next;
        }
        //同时移动两个指针,直到pre指针到达尾端,此时later指针的位置即为所求位置
        while (pre.next != null) {
            pre = pre.next;
            later = later.next;
        }
        return later.element;
    }

    @Override
    public String toString() {
        if (headerNode == null) {
            return "[]";
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            sb.append(headerNode.element);
            ListNode<E> firstNode = headerNode;
            ListNode<E> iterator = firstNode.next;
            while (iterator != null) {
                sb.append(",").append(iterator.element);
                iterator = iterator.next;
            }
            return sb.append("]").toString();
        }
    }

    static class ListNode<E> {
        private E element;
        private ListNode<E> next;

        ListNode(E element) {
            this.element = element;
            next = null;
        }

        ListNode() {
        }
    }

    private String outOfBoundsMsg(int index) {
        return "Index: "+index+", Size: "+ size();
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值