当前位置: 首页 > news >正文

数据结构和算法篇--带哨兵节点的双链表

列表接口类

package com.madooei.cb;/*** @title CS226List** Generic List ADT.** @param <T> the type of elements stored in this list** 请注意:这是骨架代码,请不要修改。如需改动,请复制一份。*/
public interface CS226List<T> extends Iterable<T>{void add(T element);T get(int index);void remove(int index);int size();// Inherited from Iterable<T>:// Iterator<T> iterator();}

带哨兵节点的双链表类

package com.madooei.cb;import java.util.Iterator;
import java.util.NoSuchElementException;/*** @title SDLList* @description 带哨兵节点的双链表** Sentinel Double Linked List** 注意:不是环形链表**/
public class SDLList<T> implements CS226List<T>{// 内部类private class Node {T data;Node prev;Node next;public Node(T data) {this.data = data;this.prev = null;this.next = null;}public Node() {this.data = null;this.prev = null;this.next = null;}}private Node head;private Node tail;private int size;// head->sentinelHead->sentinelTail// tail->sentinelTail->sentinelHeadpublic SDLList() {head = new Node();tail = new Node();head.next = tail;tail.prev = head;size = 0;}@Overridepublic void add(T element) {addLast(element);}//初始:空链表// head->sentinelHead->sentinelTail// tail->sentinelTail->sentinelHead//操作:插入a//目标:// sentinelHead->a->sentinelTail// sentinelTail->a->sentinelHead//操作:插入b//目标:// sentinelHead->b->a->sentinelTail// sentinelTail->a->b->sentinelHeadpublic void addFirst(T element){Node newNode = new Node(element);newNode.next = head.next;head.next.prev = newNode;newNode.prev = head;head.next = newNode;size++;}//初始:空链表// head->sentinelHead->sentinelTail// tail->sentinelTail->sentinelHead//操作:插入a//目标:// sentinelHead->a->sentinelTail// sentinelTail->a->sentinelHead//操作:插入b//目标:// sentinelHead->a->b->sentinelTail// sentinelTail->b->a->sentinelHeadpublic void addLast(T element){Node newNode = new Node(element);newNode.prev = tail.prev;tail.prev.next = newNode;newNode.next = tail;tail.prev = newNode;size++;}@Overridepublic T get(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("数组越界#index="+index+"#size="+size);}Node current = head.next;for (int i = 0; i < index; i++) {current = current.next;}return current.data;}@Overridepublic void remove(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("数组越界#index="+index+"#size="+size);}Node current = head.next;for (int i = 0; i < index; i++) {current = current.next;}deleteNode(current);size--;}public boolean remove(T element) {Node current = head.next;while (current != null) {if (current.data.equals(element)) {deleteNode(current);  // Helper methodsize--;return true;}current = current.next;}return false;}private void deleteNode(Node target) {target.prev.next = target.next;target.next.prev = target.prev;}@Overridepublic int size() {return size;}@Overridepublic Iterator<T> iterator() {return new LinkedListIterator();}private class LinkedListIterator implements Iterator<T> {private Node current = head.next;@Overridepublic boolean hasNext() {return current != tail;}@Overridepublic T next() {if (!hasNext()) {  // 检查是否还有元素throw new NoSuchElementException("No more elements in iterator");}T element = current.data;current = current.next;return element;}}public void checkInvariants() {// 1. head 和 tail 必须存在if (head == null || tail == null) throw new AssertionError("Sentinels missing");// 2. head.prev 和 tail.next 必须为 nullif (head.prev != null) throw new AssertionError("head.prev must be null");if (tail.next != null) throw new AssertionError("tail.next must be null");// 3. 检查 next.prev 一致性Node current = head;while (current.next != null) {if (current.next.prev != current)throw new AssertionError("Broken next.prev at node " + current);current = current.next;}// 4. 检查 prev.next 一致性current = tail;while (current.prev != null) {if (current.prev.next != current)throw new AssertionError("Broken prev.next at node " + current);current = current.prev;}// 5. 遍历计数与 size 一致int count = 0;current = head.next;while (current != tail) {count++;current = current.next;}if (count != size)throw new AssertionError("Size mismatch: expected " + size + ", found " + count);}
}

带哨兵节点的双链表测试类

package com.madooei.cb;import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Random;/*** @title SDLListTest* @description 带哨兵节点的双链表测试类*/
public class SDLListTest {@Testpublic void testEmpty(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.checkInvariants();}@Testpublic void testAdd(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.add("a");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals(1, list.size());list.add("b");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals(2, list.size());list.add("c");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals("c", list.get(2));Assertions.assertEquals(3, list.size());}@Testpublic void testFrontAdd(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.addFirst("a");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals(1, list.size());list.addFirst("b");list.checkInvariants();Assertions.assertEquals("b", list.get(0));Assertions.assertEquals("a", list.get(1));Assertions.assertEquals(2, list.size());list.addFirst("c");list.checkInvariants();Assertions.assertEquals("c", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals("a", list.get(2));Assertions.assertEquals(3, list.size());}@Testpublic void testTailAdd(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.addLast("a");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals(1, list.size());list.addLast("b");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals(2, list.size());list.addLast("c");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals("c", list.get(2));Assertions.assertEquals(3, list.size());}@Testpublic void testFrontRemove(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.add("a");list.add("b");list.add("c");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals("c", list.get(2));Assertions.assertEquals(3, list.size());int rnd = 0;list.remove(rnd);list.checkInvariants();Assertions.assertEquals(2, list.size());list.remove(rnd);list.checkInvariants();Assertions.assertEquals(1, list.size());list.remove(rnd);list.checkInvariants();Assertions.assertEquals(0, list.size());}@Testpublic void testRandomIndexRemove(){SDLList<String> list = new SDLList<>();Assertions.assertEquals(0, list.size());list.add("a");list.add("b");list.add("c");list.checkInvariants();Assertions.assertEquals("a", list.get(0));Assertions.assertEquals("b", list.get(1));Assertions.assertEquals("c", list.get(2));Assertions.assertEquals(3, list.size());Random random = new Random();int rnd = random.nextInt(list.size());list.remove(rnd);Assertions.assertEquals(2, list.size());list.checkInvariants();rnd = random.nextInt(list.size());list.remove(rnd);Assertions.assertEquals(1, list.size());list.checkInvariants();rnd = random.nextInt(list.size());list.remove(rnd);Assertions.assertEquals(0, list.size());list.checkInvariants();}@Testpublic void testGetOutOfBounds() {SDLList<Integer> list = new SDLList<>();list.add(1);list.add(2);Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(-1));Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.get(2));}@Testpublic void testRemoveOutOfBounds() {SDLList<Integer> list = new SDLList<>();list.add(1);Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(-1));Assertions.assertThrows(IndexOutOfBoundsException.class, () -> list.remove(1));}@Testpublic void testRemoveObjectNotFound() {SDLList<String> list = new SDLList<>();list.add("a");list.add("b");Assertions.assertFalse(list.remove("c"));list.checkInvariants();Assertions.assertEquals(2, list.size());}@Testpublic void testRemoveObjectFound() {SDLList<String> list = new SDLList<>();list.add("a");list.add("b");Assertions.assertTrue(list.remove("a"));list.checkInvariants();Assertions.assertEquals(1, list.size());Assertions.assertEquals("b", list.get(0));}@Testpublic void testIteratorForward() {SDLList<String> list = new SDLList<>();list.add("a");list.add("b");list.add("c");Iterator<String> it = list.iterator();Assertions.assertTrue(it.hasNext());Assertions.assertEquals("a", it.next());Assertions.assertEquals("b", it.next());Assertions.assertEquals("c", it.next());Assertions.assertFalse(it.hasNext());}@Testpublic void testIteratorEmptyList() {SDLList<String> list = new SDLList<>();Iterator<String> it = list.iterator();Assertions.assertFalse(it.hasNext());Assertions.assertThrows(NoSuchElementException.class, it::next);}@Testpublic void testIteratorNextBeyondEnd() {SDLList<String> list = new SDLList<>();list.add("x");Iterator<String> it = list.iterator();Assertions.assertEquals("x", it.next());Assertions.assertThrows(NoSuchElementException.class, it::next);}@Testpublic void testMixedOperations() {SDLList<Integer> list = new SDLList<>();list.addFirst(1); // 1list.addLast(2);  // 1,2list.addFirst(0); // 0,1,2list.checkInvariants();Assertions.assertEquals(3, list.size());Assertions.assertEquals(0, list.get(0));Assertions.assertEquals(2, list.get(2));list.remove(1); // remove 1 -> 0,2list.checkInvariants();Assertions.assertEquals(2, list.size());}}
http://www.dtcms.com/a/438367.html

相关文章:

  • 6黄页网站建设做网站怎么去工信部缴费
  • 三支一扶面试资料
  • pytorch 52 基于SVD从全量训练模型中提取lora模型
  • Process Monitor 学习笔记(5.7):长时间运行追踪与日志体积控制
  • 深入解析需求变更:从本质认知到实践指南
  • 商城网站建设的步骤网络设计教程
  • Day 30 - 错误、异常与 JSON 数据 - Python学习笔记
  • 吴恩达机器学习笔记(10)—支持向量机
  • 电商网站建设与运行xd网页设计教程
  • 基于websocket的多用户网页五子棋(四)
  • 深入浅出 C++20 协程
  • 想做个小网站怎么做主机壳 安装wordpress
  • 永兴县网站建设专业山东省城乡建设厅官网
  • ip prefix-list(IP前缀列表)概念及题目
  • [工作流节点9] 删除记录节点的风险与使用规范 —— 明道云工作流数据清理实战指南
  • 做网站推广的销售怎么打电话如何做网站发产品销售
  • MongoDB GEO 项目场景 ms-scope 实战
  • 医美三方网站怎么做网站外链建设可以提升网站
  • 在算法比赛中高效处理多行输入
  • MySQL 管理与配置详解:从安装到架构解析
  • 构建工具webpack
  • 深入理解 Rust 的内存模型:变量、值与指针
  • 单位网站备案要等多久湖南住建云网站
  • 浦口区网站建设售后服务有没有做卡商的网站
  • 可达鸭模拟赛1
  • LINUX复习资料(一)
  • 专业做酒的网站有哪些互联网营销培训班 考证
  • 串扰09-Er与串扰
  • HarmonyOS应用开发深度解析:ArkTS语法与组件化开发实践
  • 免费的简历制作网站100大看免费行情的软件