单向链表的API实现

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

单向链表的API设计:

在这里插入图片描述

package com.jinglan.basics;

public class LinkedList<T> {
	private Node head; // 记录头结点
	private int N; // 记录链表的长度

	private class Node {// 结点类
		T item;// 存储数据
		Node next;// 下一个结点

		public Node(T item, Node next) {
			this.item = item;
			this.next = next;
		}
	}

	// 构造方法
	public LinkedList() {
		// 1、初始化头结点
		this.head = new Node(null, null);// 头结点不存数据,默认情况下链表为空不指向下一结点
		// 2、初始化元数个数
		this.N = 0;
	}

	// 清空链表
	/*
	 * 原理: 当头结点不指向任何结点并且链表中元数个数为0时 当前链表为空
	 */
	public void clear() {
		head.next = null;
		this.N = 0;
	}

	// 获取链表的长度
	/*
	 * 原理: 长度即为元素个数 返回N即可
	 */
	public int length() {
		return N;
	}

	// 判断链表是否为空
	/*
	 * 原理: 如果链表中没有元素,那说明当前链表为空 所以只需要判断元素个数是否为0,为0则链表为空,不为0则链表不为空
	 */
	public boolean isEmpty() {
		return N == 0;
	}

	// 获取指定位置i处的元素
	/*
	 * 原理: 通过循环,从头结点开始往后找,依次找i次,就可以找到对应的元素。
	 */
	public T get(int i) {
		Node n = head.next;// 记录头结点
		for (int index = 0; index < i; index++) {
			n = n.next;// 不断地把n向后变化
		}
		return n.item;// 返回第i个位置处存储的元素
	}

	// 向链表中添加元素t
	public void insert(T t) {
		// 尾插
		/*
		 * 步骤: 找到当前链表的最后一个结点 创建新结点,保存元素 让当前最后一个结点指向新结点 元素的个数+1
		 */
		Node n = head;// 将n的值初始化为头结点
		while (n.next != null) {// 如果n的下一个结点不为null,那就一直往下循环,直到为null时跳出循环,此时n记录的就是链表的尾结点
			n = n.next;
		}
		Node newnode = new Node(t, null);// 创建新结点
		n.next = newnode;// 让它作为新的尾结点
		// 链表中的元素个数加一
		N++;
	}

	// 向指定位置i处,添加元素t
	public void insert(int i, T t) {
		/*
		 * 原理 将i位置所代表的结点的前一个结点的后继改为新结点(要插入的结点 t) 然后再把新结点的后继改为i位置所代表的结点
		 */
		// 1、找出i位置的前一个结点
		Node pre = head;// 默认i位置的前一个结点为头结点,然后通过循环去找到并修正
		for (int index = 0; index <= i - 1; i++) {// i位置的前一个结点的位置就是i-1
			pre = pre.next;// 找到了就跳出循环,并且此时pre记录的就是第i-1个结点
		}
		// 2、找到i位置的结点
		Node curr = pre.next;// i位置的结点就是pre的下一个
		// 3、创建新结点,并且新结点指向原来i位置的结点
		Node newNode = new Node(t, curr);
		// 4、原来i位置的前一个结点指向新结点即可
		pre.next = newNode;
		// 5、链表元素的个数加一
		N++;
	}

	// 删除指定位置i处的元素,并返回被删除的元素
	public T remove(int i) {
		/*
		 * 原理: 将i位置所代表的结点的前一个结点直接指向i位置的后一个结点
		 */
		// 1、找到i位置的前一个结点
		Node pre = head;// 默认i位置的前一个结点为头结点,然后通过循环去找到并修正
		for (int index = 0; index <= i - 1; i++) {
			pre = pre.next;// 找到了就跳出循环,并且此时pre记录的就是第i-1个结点
		}
		// 2、找到i位置的结点
		Node curr = pre.next;
		// 3、找到i位置的后一个结点
		Node nextNode = curr.next;// i的前一个结点通过循环得出了是pre,pre.next是结点,pre.next.next是i的后一个结点
		// 4、让i位置的前一个结点指向i位置的后一个结点
		pre.next = nextNode;
		// 5、链表元素的个数减一
		N--;
		return curr.item;
	}

	// 查找元素t在链表中第一次出现的位置
	public int indexOf(T t) {
		/*
		 * 原理: 遍历链表,找到之后拿出数据(item)并将它与t相比较,如果相同返回i位置,如果没有就继续找
		 */
		// 从头结点开始依次找到每一个结点取出item和t比较
		Node n = head;
		for (int i = 0; n.next != null; i++) {
			n = n.next;
			if (n.item.equals(t)) {
				return i;
			}
		}
		return -1;// 当前链表中不存在与t一样的元素
	}
}

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

立志Java工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值