已知一个有序单链表L(允许出现值域重复的结点),设计一个高效算法删除值域重复的结点,并分析算法的时间复杂度。
解:由于是有序单链表,所以相同值域的结点都是相邻的。用p扫描递增单链表,若p所指结点的值域等于后继点的值域,则删除后者。
实现代码如下:
#include <stdio.h>
#include <malloc.h>
typedef int ElemType;
typedef struct LNode
{
ElemType data;
struct LNode *next;
} LinkNode;
void CreateListF(LinkNode *&L,ElemType a[],int n)
//头插法建立单链表
{
LinkNode *s;
L=(LinkNode *)malloc(sizeof(LinkNode)); //创建头结点
L->next=NULL;
for (int i=0;i<n;i++)
{
s=(LinkNode *)malloc(sizeof(LinkNode));//创建新结点s
s->data=a[i];
s->next=L->next; //将结点s插在原开始结点之前,头结点之后
L->next=s;
}
}
void DispList(LinkNode *L)
{
LinkNode *p=L->next;
while (p!=NULL)
{ printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
void dels(LinkNode *&L)
{
LinkNode *p=L->next,*q;
while (p->next!=NULL)
{
if (p->data==p->next->data) //找到重复值的结点
{
q=p->next; //q指向这个重复值的结点
p->next=q->next; //删除*q结点
free(q);
}
else //不是重复结点,p指针下移
p=p->next; //同时开启下一个循环从第二个元素开始
}
}
void DestroyList(LinkNode *&L)
{
LinkNode *pre=L,*p=pre->next;
while (p!=NULL)
{ free(pre);
pre=p;
p=pre->next;
}
free(pre); //此时p为NULL,pre指向尾结点,释放它
}
int main()
{
LinkNode *L;
ElemType a[]={1,2,2,2,3,3,3,3,3};
CreateListF(L,a,9);
printf("L:"); DispList(L);
dels(L);
printf("L:"); DispList(L);
DestroyList(L);
return 0;
}

本文介绍了一种针对有序单链表设计的高效算法,通过遍历链表并删除相邻重复值结点,以保持链表有序且无重复。通过示例代码展示了如何实现在C语言中操作,并分析了算法的时间复杂度。
6889

被折叠的 条评论
为什么被折叠?



