1.问题
给定一个没有排序的链表,去掉起重复项,并保留原顺序,原链表1---3---1--5---5--7 去掉重复项之后,变为1--3---5---7
2 思路分析(循序删除)
通过双层循环来实现
1) 外层循环遍历链表
2)内层循环从当前外层循环的节点的后一个节点开始循环
3)内层循环需要定义一个前驱辅助指针,和当前节点
4)当内层循环发现与外层当前节点相同的数据时, 前驱节点的后继指针 指向 当前节点的后继指针,(删除当前节点),当前节点后移。否则前驱节点和当前节点后移。继续遍历
3代码实现
package linkedlist.quchong;
public class remove {
public static void main(String[] args) {
int i=1;
//头结点
LNode head=new LNode();
head.next=null;
LNode tmp=null;
LNode cur=head;
for (;i<7;i++){
tmp=new LNode();
if (i%2==0){
tmp.date=i+1;
}else if (i%3==0){
tmp.date=i-2;
}else {
tmp.date=i;
}
tmp.next=null;
cur.next=tmp;
cur=tmp;
}
System.out.println("删除重复节点之前");
for (cur=head.next;cur!=null;cur=cur.next){
System.out.print(cur.date+" ");
}
removeDup(head);
System.out.println("删除重复节点之后");
for (cur=head.next;cur!=null;cur=cur.next){
System.out.print(cur.date+" ");
}
}
public static void removeDup(LNode head){
if (head==null || head.next==null){
return;
}
LNode outcur=head.next;//用于外层循环,指向链表的第一个节点
LNode innercur=null;//用于内层循环 用来遍历 outcur 之后的节点
LNode innerpre=null;//内层的前驱节点
for (;outcur!=null;outcur=outcur.next){
for (innercur=outcur.next,innerpre=outcur;innercur!=null;){
if (innercur.date==outcur.date){
innerpre.next=innercur.next;
innercur=innercur.next;//后移
}else {
innerpre=innercur;
innercur=innercur.next;
}
}
}
}
}
class LNode{
LNode next;
int date;
}
4 方法二:递归法
private static LNode removeDupRecursion(LNode head){
if (head.next==null){
return head;
}
LNode pointer=null;
LNode cur=head;
//对以head.next为首的子链表删除重复节点
head.next=removeDupRecursion(head.next);
pointer=head.next;
//找出以head.next为首的子链表中与head节点相同的节点,并删除
while (pointer!=null){
if (head.date==pointer.date){
cur.next=pointer.next;
pointer=cur.next;
}else {
pointer=pointer.next;
cur=cur.next;
}
}
return head;
}
//对带头结点的单链表删除重复节点的输入参数
public static void removeDup1(LNode head){
if (head==null){
return;
}
head.next=removeDupRecursion(head.next);
}