以下代码通过两种不同的方法实现了删除链表中的重复元素。
方法一:遍历链表,把遍历到的值存储到一个Hashtable中,在遍历过程中,若当前访问的值在Hashtable中已经存在,则说明这个数据是重复的,因此就可以删除。
- 优点:时间复杂度低。
- 缺点:在遍历过程中需要额外的存储空间来保存已遍历过的值。
方法二:对链表进行双重循环遍历,外循环正常遍历链表,假设外循环当前遍历的结点为cur,内循环从cur开始遍历,若碰到与cur所指向结点值相同,则删除这个重复结点。
- 优点:不需要额外的存储空间。
- 缺点:时间复杂度高。
import java.util.Hashtable;
/*
* 如何从链表中删除重复元素
*/
//定义结点类,存储结点信息
class Node{
Node next = null;
int data;
public Node(int data) {
this.data = data;
}
}
public class LinkedList {
Node head = null;//链表头的引用
/**
* 向链表中插入数据(末尾依次增加)
* @param d:插入数据的内容
*/
public void addNode(int d) {
Node newNode = new Node(d);
if(head == null) {//链表为空
head = newNode;
return;
}
Node temp = head;
while(temp.next != null) {
temp = temp.next;
}
//在链表末尾插入元素
temp.next = newNode;
}
/**
* 输出当前链表的数据
*/
public void printList() {
Node temp = head;
while(temp != null) {
System.out.println(temp.data);
temp = temp.next;
}
}
/**
* 法一:遍历链表,把遍历到的值存储到一个Hashtable中,在遍历过程中,
* 若当前访问的值在Hashtable中已经存在,则说明这个数据是重复的,因此就可以删除。
* @param head:传入的参数是链表的头结点
*/
public void deleteRepetition_1(Node head) {
Hashtable<Integer, Integer> table = new Hashtable<Integer, Integer>();
Node temp = head;
Node pre = null;
while(temp != null) {//如果链表不为空
if(table.containsKey(temp.data)) {//如果已含有相同的数据,则删除
pre.next = temp.next;
}else {//否则,将其添加进Hashtable
table.put(temp.data, 1);
pre = temp;
}
temp = temp.next;
}
}
/**
* 法二:对链表进行双重循环遍历,外循环正常遍历链表,假设外循环当前遍历的结点为cur,
* 内循环从cur开始遍历,若碰到与cur所指向结点值相同,则删除这个重复结点。
* @param head:传入参数是链表的头结点
*/
public void deleteRepetition_2(Node head) {
Node p = head;
while(p != null) {//p作为外循环
Node q = p;
while(q.next != null) {//q作为内循环
if(p.data == q.next.data) {
//内循环在遍历过程中会删除与当前结点值相同的所有结点
q.next = q.next.next;
}else {
q = q.next;
}
}
p = p.next;
}
}
public static void main(String[] args) {
LinkedList list = new LinkedList();
list.addNode(1);
list.addNode(2);
list.addNode(3);
list.addNode(1);
list.addNode(5);
System.out.println("删除重复元素前:");
list.printList();
list.deleteRepetition_2(list.head);
System.out.println("删除重复元素后:");
list.printList();
}
}
程序输出结果如下:
删除重复元素前:
1
2
3
1
5
删除重复元素后:
1
2
3
5