删除重复结点(链表)
- 有一个递增非空单链表,设计一个算法删除值域重复的结点。例如,{1,1,2,3,3,3,4,4,7,7,7,9,9,9}经过删除后变成{1,2,3,4,7,9}.
思路一:
可以用一个指针p指向起始结点,如果p所指的值等于后继结点的值,则删除后继节点;否则p就指向后继节点。重复以上过程,直到p的后继节点为空。
代码一:
void delsl1 (LNode *L){
LNode *p=L->next,*q; //定义两个指针,其中q指向起始结点
while (p->next != NULL){ //当p的后继结点不为空时执行
if (p->data == p->next->data){ //找到重复结点并删除
q = p->next; //将p后继节点的地址给q
p->next = q->next; //用q的后继节点的地点覆盖p的后继节点的地址(即将p后第二个结点覆盖p紧接的结点)
free(q); //释放q的空间
}else{
p = p->next; //不重复则p后移一个位置
}
}
}
思路二:
将每个重复的元素的第一个元素移到链表的前端,然后将剩余的元素删除。
用两个指针 p,q 分别指向起始结点和起始节点的后继节点。当 p->data 等于 q->data 时,不需要管,直接q往后走;当 p->data 不等于 q->data 时,p往后走一步,然后再让 p->data = q->data(即将q指针所指的值赋给p),最后当 q 为空时,释放 p 后面的所有结点空间
代码二:
void delsl2 (LNode *L){
LNode *p = L->next, *q = L->next->next, *r; //创建p,q指针和r指针
while (q!=NULL){ //当q不为空时执行
while (q!=NULL && p->data == q->data) //当q不为空且p的结点值和q的结点值相等时执行
q = q->next; //q往后走
if (q!=NULL) //当q不为空时,即q往后移之后还在表中
p = p->next; //p往后走
p->data = q->data; //q的值赋给p
}
q = p->next; //当q为空时,把q指向p的后继节点
p->next = NULL; //把p的后继置空
while (q!=NULL){ //当q不为空时执行
r = q; //把q指针给r
q = q->next; //q往后走一步
free(r); //释放r的空间
}
}