单向链表算法

本文介绍了链表作为动态数据结构的基本概念,强调了单向链表的特点,包括节点结构和头尾节点的定义。并提及将提供相关代码实现。

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

链表是一种线性数据结构,使用它能动态地存储一种数据结构。链表是n个数据元素的有限序列,其元素需要自己定义,既可以是一个整数或一个字符串,也可以是一个复杂的记录类型。

链表结构由节点构成,每个节点包含两部分数据,第一部分是节点本身的数据,第二部分是指向下一个节点的指针。对于单向链表,链表中存在两个特殊的节点,分别为“头节点”和“尾节点”。头节点本身没有数据,只存储下一个节点的指针,尾节点只存储数据。

代码如下:

import org.junit.Test;

class ListNode {
	public ListNode nextNode;// 指向下一个节点的指针
	public int value;

	public ListNode() {

	}

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

public class LinkedListImpl {
	private ListNode headNode = new ListNode();// 头节点
	private ListNode tailNode;// 尾节点
	private int listCount;// 链表数据的个数

	// 初始化
	public LinkedListImpl() {
		headNode.nextNode = null;
		tailNode = null;
		listCount = 0;
	}

	/*
	 * 尾插法,将数据插入到链表中
	 */
	public void append(int value) {
		ListNode newNode = new ListNode(value);
		if (listCount == 0) {// 当链表为空时,第一个插入进来的节点既是头又是尾
			headNode.nextNode = newNode;// 头节点是空的,第一个数实际上是第二个节点
			tailNode = newNode;
		} else {
			tailNode.nextNode = newNode;// 将新的节点插入到链表尾部
			tailNode = newNode;// 新插入的节点变为尾节点
		}
		listCount++;// 链表节点个数+1(不算上头节点)
	}

	/*
	 * 在指定值为e的节点后插入数据value
	 */
	public void insert(int e, int value) {
		if (listCount == 0) {
			// 为空表时,则直接添加数据
			append(value);
			return;
		}
		// 查找值为e的节点
		ListNode node = search(e);
		if (node == tailNode) {
			// 如果指定的节点是尾节点,则直接添加数据
			append(value);
			return;
		}
		ListNode newNode = new ListNode(value);

		// 将数据添加到链表的中间,先将指定的节点的nextNode连到新节点之后,再将新节点连到指定的节点之后
		newNode.nextNode = node.nextNode;
		node.nextNode = newNode;
		listCount++;
	}

	/*
	 * 查找值为e的节点
	 */
	public ListNode search(int e) {
		ListNode node = null, pNode = headNode.nextNode;
		while (pNode != null) {
			if (pNode.value == e) {
				node = pNode;
				break;
			} else {
				pNode = pNode.nextNode;
			}
		}
		return node;
	}

	/*
	 * 删除指定值的节点
	 */
	public void delete(int e) {
		ListNode node = searchPre(e);
		// 删除节点,将其前面的节点的指针指向其后面的节点即可
		node.nextNode = node.nextNode.nextNode;
	}

	/*
	 * 查找指定值为e的节点的前一个节点,
	 * 将头节点设置为null,目的就是为了方便查找指定节点的前一个节点方便,这样的话,每一个有值的节点都有前一个节点了
	 */
	public ListNode searchPre(int e) {
		ListNode node = null, pNode = headNode;

		while (pNode.nextNode != null) {
			if (pNode.nextNode.value == e) {
				node = pNode;
				break;
			} else {
				pNode = pNode.nextNode;
			}
		}
		return node;
	}

	/*
	 * 打印链表
	 */
	public void print() {
		ListNode pNode = headNode.nextNode;
		while (pNode != null) {
			System.out.print(pNode.value + " ");
			pNode = pNode.nextNode;
		}
		System.out.println();
	}

	// 测试
	@Test
	public void test() {
		LinkedListImpl list = new LinkedListImpl();
		for (int i = 1; i < 10; i++)
			list.append(i);
		list.print();

		list.insert(8, 99);
		list.print();

		list.delete(4);
		list.print();
		/*
		 * 测试结果:
		 * 1 2 3 4 5 6 7 8 9 
		 * 1 2 3 4 5 6 7 8 99 9 
		 * 1 2 3 5 6 7 8 99 9
		 */
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值