这道题就是对单链表去重,主要考查的是单链表删除和遍历操作,删除单链表的结点必须知道前驱是谁
思路:
1.定义三个结构体指针,指针一用来指向第一个结点,指针二指向第一个结点,指针三指向第二个结点,如果第二个结点与第一个结点重复,则删除指针三所指的结点;不重复则依次移动二,三指针,重复以上操作。
2.遍历完一遍单链表之后,再将指针一移动到下一个位置,重复以上操作
3.注意尾结点的特殊情况
#include <stdio.h>
#include <stdlib.h>
typedef struct linklist{
int data;
struct linklist *next;
}LNode,*link;
int ListLength(link L)
{
link p=L;int sum=0;
while(p)
{
sum++;
p=p->next;
}
return sum-1;//去除头结点
}
int abs(int a){
if(a>=0) return a;
return(a*(-1));
}
void update(link HEAD){
link p=HEAD;
int len=ListLength(HEAD);//不包括头指针
link q;link r;
for(int i=1;i<=len-1;i++){
p=p->next;//记录一个data,开始遍历链表
int t=p->data;
r=p;
q=r->next;
while(1){
if(abs(t)==abs(q->data)){//abs()为取绝对值函数
//如果q为尾结点
if(q->next==NULL){
r->next=NULL;
free(q);
}else{
r->next=q->next;
free(q);//释放掉删除的结点
q=r->next;
}
len--;
}
if(r->next==NULL||(q->next==NULL&&abs(t)!=abs(q->data))) break;
if(abs(t)!=abs(q->data)){
r=r->next;
q=q->next;
}
}
}
}
void PrintList(link L)
{
link p=L;//link p=L->next;//跳过头结点
if(ListLength(L))
{
printf("当前单链表所有元素:");
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
else
{
printf("当前单链表已空!\n");
}
}
int main()
{
LNode HEAD,a,b,c,d,e;
HEAD.next=&a;
a.data=21;
b.data=15;
c.data=15;
d.data=-7;
e.data=15;
a.next=&b;
b.next=&c;
c.next=&d;
d.next=&e;
e.next=NULL;
printf("原单链表元素为:21,15,15,-7,15\n");
update(HEAD.next);
PrintList(HEAD.next);
return 0;
}
运行结果为: