一、实验题目
(1)实验题目
用单链表实现集合
(2)问题描述
用有序单链表实现集合的判等、交、并和差等基本运算。
二、实验内容
(1)采用有序单链表存储集合;
(2)实现交、并、差等基本运算时,要求算法的空间复杂度为 O(1);
(3)充分利用单链表的有序性,要求算法有较好的时间性能;
(4)分析算法的时空性能,设计测试数据并上机实现。
三、数据结构设计
//节点结构
static class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
//判断集合 A 和 B 是否相等
public boolean isEqual(ListNode curA , ListNode curB)
//求集合 A 和 B 的交集
public ListNode Interest(ListNode curA , ListNode curB)
//求集合 A 和 B 的并集
public ListNode union(ListNode curA , ListNode curB)
//差集
public ListNode subtraction(ListNode curA , ListNode curB)
四、算法设计
(1)判断集合 A 和 B 是否相等
public boolean isEqual(ListNode curA , ListNode curB)
同时遍历A链表和B链表
ListNode pa = curA
ListNode pb = curB
循环条件:pa != null && pb != null
如果pa.val!=pb.val,返回false,如果pa.val=pb.val,pa=pa.next,pb=pb.next,直到循环 结束。如果两个链表都为空,直接返回true,否则返回false.
时间复杂度:O(N)
空间复杂度:O(1)
(2)求集合 A 和 B 的交集
public ListNode Interest(ListNode curA , ListNode curB)
ListNode pa = curA
ListNode pb = curB
首先循环遍历B链表,每遍历一个节点,去遍历链表A,如果A链表的值小于 B节点的值,需要将该节点删除,删除就需要定义prev,让prev指向要删除节点的前驱节点,prev.next = pa.next,当pa.val=pb.val,说明链表A中包含pa节点,让prev = pa,pa=pa.next,pb=pb.next,如果pa.val> pb.val,pb=pb.next.
最终返回A链表的头节点即可。
时间复杂度:O(N^2)
空间复杂度:O(1)
(3)求集合 A 和 B 的并集
public ListNode union(ListNode curA , ListNode curB)
遍历B链表的每个节点,每遍历到一个节点去判断A链表中是否包含该节点如果A链表中该节点,pb=pb.next,同时再次循环A链表中的每个节点,如果A链表中不包含该节点,使用尾插法将该节点插入到A链表中,prev .next = pb; prev = prev.next , prev.next = null;注意,将该链表插入到A链表后,需要将尾节点的next域置null,为了能够找到B链表的下一个节点,需要引入ListNode pbNext = pb.next;,定义在B链表每次进入循环的时候,防止找不到B链表的后续节点。
时间复杂度:O(N^2)
空间复杂度:O(1)
(4)差集
public ListNode subtraction(ListNode curA , ListNode curB)
遍历B链表的每个节点,遍历到每个节点的同时,遍历A链表,如果A链表中包含该节点,需要将该节点删除,如果不包含该节点,继续遍历B链表中的下一个节点即可。
时间复杂度:O(N^2)
空间复杂度:O(1)
五、运行结果 
七、程序源码
```java
public class MyLinkedList {
//节点结构
static class ListNode {
public int val;
public ListNode next;
public ListNode(int val) {
this.val = val;
}
}
public ListNode createList(String str){
LinkedList<ListNode> list = new LinkedList<>();
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
int n = Integer.valueOf(ch)-48;
ListNode node = new ListNode(n);
list.add(node);
}
for