#include <stdio.h>
#include <malloc.h>
struct cell {//单链表结点结构体定义
int x;
struct cell* next; };
struct cell* build(void) {//新建单链表,并将建好的单链表首结点地址返回
struct cell* head, * tmp, * p;
head = tmp = p = NULL;
int n; /*请在以下位置补充完整,实现函数build的功能 ...... ...... ...... */
while(scanf("%d",&n),n!=0)
{p=(struct cell*)malloc(sizeof(struct cell));//必须申请空间,不然出错
p->x=n;
p->next=NULL;
if(head==NULL)//如果不把头结点更新,就会导致头结点与后面的元素断裂,出错
{
head=p;
tmp=p;
}
else{
tmp->next=p;//尾插法,先把新结点数据写好,next为null,再把尾结点更新,尾结点的ext一定是null;
tmp=p;
}
}
return head;}
struct cell* del2one(struct cell* head) {//删除重复结点只保留一个,head是单链表首结点指针
struct cell*p, * pre,*q;//需要双重循环依次比较所有要两个指针,但是要删除必须知道删除元素的前驱,所有还需要有一个指针q,来记录pre的前驱
p=head;
while(p!=NULL)
{ pre=p->next;//从p的下一个元素开始遍历,q在pre前面;
q=p;
while(pre!=NULL)
{
if(p->x==pre->x)
{
q->next=pre->next;//删除操作,删除pre后释放pre结点空间,更新pre的位置
free(pre);
pre=q->next;
}else{//如果相同则pre,q都不用再动,因为删除的时候已经更新过了,在更新会导致有元素没有遍历到。只有不同的时候才往下更新
if(pre!=NULL){
pre=pre->next;//在删除链表最后一个元素的时候,如果在对pre->next进行引用就会导致空指针引用错误
q=q->next;
}
}
}
p=p->next;
}
return head;//返回删除重复结点的单链表头
}
void print(struct cell* head) {//打印整个单链表,head是单链表首结点指针
struct cell*p;
p=head;
while(p!=NULL)
{if(p->next==NULL)
{
printf("%d",p->x);
p=p->next;//老是忘记这个,如果没有这条语句就会无限循环,因为p不会==NULL;
}
else
{printf("%d ",p->x);
p=p->next;
}
}
}
void release(struct cell* head) {//释放单链表空间,head是单链表首结点指针
struct cell*p,*a;
p=head;
while(p!=NULL)
{
a=p->next;
free(p);
p=a;
}
}
int main(void) {
struct cell* head;
head = build();
head=del2one(head);
if(head!=NULL)
print(head);
else
printf("NULL");
release(head);
return 0; }
写在注释里了,直接看代码,这是我自己犯过的错误,所以记着