- 练习题-删除有序单链表中的重复元素(C语言实现)
- 一、题目
- 二、思路
- 三、代码实现
- 四、全部代码
- 五、测试
如题所述,是对单链表进行操作,而且链表是有序的,意味着重复元素都是挨在一块儿的,如下图所示:
或者是这样的:
二、思路 既然重复元素都是连续挨着的,那么我们可以设置一个快慢指针,用temp指向上一个元素的值,p指向当前元素,如果p所指和temp所指元素相等,那么把p所指的结点删除,temp保持不动,p指针后移;如果p所指和temp所指元素不等,那么temp向后移动,即temp等于p,然后再把p后移,直到p指向单链表的末尾。如下图:
三、代码实现bool Del_duplicate(linkList *B)
{
linkList *q,*temp;
q = B->next;
temp = q;//temp是慢指针,指向q的前驱
q = q->next;//q往后移动
while(q->next!=NULL)
{
if(q->data == temp->data)//如果p当前指向的元素和前面的结点元素相同则删除p所指结点
temp->next = q->next;//执行删除操作
else
temp = q;//如果不等则更新temp,并且p继续向后移动,直到链表末尾
q = q->next;//q向后移动
}
return true;
}
这种方法实现显然比较简单,当然也还有别的方法,但是我这种方法空间复杂度为O(1),时间复杂度也只是为O(n),也还算不错了。
四、全部代码#include五、测试#include #include //根据C99标准,C语言使用bool类型需要添加这个头文件 typedef int ElemType; typedef struct linkNode { ElemType data; struct linkNode *next; }linkList; //------------ 函数声明 ----------// void MainMenu(); bool InitlinkList(linkList *B);//初始化 bool InsertlinkList(linkList *B,ElemType e);//插入 void PrintAll(linkList *B);//输出所有元素 bool Del_duplicate(linkList *B);//删除重复元素 //------------ 函数声明 ----------// int main() { linkList B; int ch; ElemType element; if(InitlinkList(&B)) printf("初始化成功!n"); else printf("初始化失败!n"); while(1) { MainMenu(); printf("请输入您要执行的操作:"); scanf("%d",&ch); switch(ch) { case 0: printf("感谢使用,已退出!"); exit(0); break; case 1: printf("请输入您要插入的元素:n"); scanf("%d",&element); if(InsertlinkList(&B,element)) printf("插入成功!n"); else printf("插入失败!n"); break; case 2: PrintAll(&B); break; case 3: if(Del_duplicate(&B)) printf("删除成功!n"); else printf("删除失败!n"); break; default: printf("您输入的操作指令有误!请重新输入!"); } } return 0; } //主菜单,显示 void MainMenu() { printf("nnn"); printf("t **** 删除有序单链表中的重复元素 ****nn"); printf("t ------- 0.退出 nn"); printf("t ------- 1.插入元素nn"); printf("t ------- 2.输出所有元素nn"); printf("t ------- 3.删除重复元素nn"); printf("t *************************************n"); } //初始化单链表(带头结点) bool InitlinkList(linkList *B) { //先申请一个头结点 linkList *head = (linkList *)malloc(sizeof(linkList)); B->next = head; head->next = NULL;//头结点之后一开始还没元素 return true; } //插入 bool InsertlinkList(linkList *B,ElemType e) { //头插法 linkList *p = B;// //申请一个新的结点 linkList *s = (linkList *)malloc(sizeof(linkList)); s->data = e;//赋值 //修改指针 将结点s插入到结点p之后 s->next = p->next;//s指针指向 p->next = s; return true; } void PrintAll(linkList *B) { linkList *q; q = B->next; //打印出所有元素 while(q->next!=NULL) { printf("%d ",q->data); q = q->next; } } bool Del_duplicate(linkList *B) { linkList *q,*temp; q = B->next; temp = q;//temp是慢指针,指向q的前驱 q = q->next;//q往后移动 while(q->next!=NULL) { if(q->data == temp->data)//如果p当前指向的元素和前面的结点元素相同则删除p所指结点 temp->next = q->next;//执行删除操作 else temp = q;//如果不等则更新temp,并且p继续向后移动,直到链表末尾 q = q->next;//q向后移动 } return true; }
输入得到一个序列:
执行删除操作之后再查看结果:
结束。



