删除重复数据的节点,删除不干净
void deleteIdentica_ListNode(PLIST list) {//删除重复数据的节点if (list == NULL) {
perror("链表地址是NULL,即将退出程序!\n");
exit(-1);
}
PNODE pFirst = list->Head.next; //指向链表第一个有真实数据的节点
PNODE pindex = list->Head.next; //指向链表第一个有真实数据的节点
PNODE pSecond = pFirst->next; //指向链表第二个有真实数据的节点
PNODE delete = NULL; //指向待删除的重复数据的节点
for (int i = 0; i < list->M_size - 1; i++) { // list->M_size 链表的有效节点
for (int j = i + 1; j < list->M_size; j++) {
if (pindex->data == pSecond->data) {
delete = pSecond;
pFirst->next = pSecond->next;
pSecond = pSecond->next;
free(delete);
list->M_size--;
}
else {
pSecond = pSecond->next;
pFirst = pFirst->next;
}
}
pindex = pindex->next;
pFirst = pindex;
pSecond = pFirst->next;
}
return;
}
//哪位大佬给看看程序有没有什么问题,为什么程序
运行后重复数据节点没有删除干净?
14592 1774 12583 32215 26879 1688 2288 2288 2288 2288 2288 2288 2288 2288 2288 2
288 8259 857 4989 11010
__________________________________
14592 1774 12583 32215 26879 1688 2288 2288 8259 857 4989 11010
__________________________________
程序运行了:30 毫秒!
系统日期:2021-11-8
系统时间:9-57-51
请按任意键继续. . .
本帖最后由 jackz007 于 2021-11-8 17:25 编辑
试试这个代码呢
void deleteIdentica_ListNode(PLIST list)
{
PLIST p1 , p2 , p3 ;
if(list) {
for(p1 = list ; p1 && p1 -> next ; p1 = p1 -> next) {
for(p3 = p1 , p2 = p3 -> next ; p2 ; p2 = p3 -> next) {
if(p2 -> data == p1 -> data) {
p3 -> next = p2 -> next;
free(p2) ;
} else {
p3 = p2 ;
}
}
}
} else {
fprintf(stderr , "Error : Empty Data Link !\n" ) ;
}
} 非常感谢!你的这个确实是精妙,可以删除干净,
这个代码我还是有些不太看得懂,需要些时间去消化;
可是我还是搞不明白我的那个代码问题出在哪里了; 本帖最后由 zhenhaowa66 于 2021-11-8 14:05 编辑
for(p1 = list ; p1 -> next ; p1 = p1 -> next) { //这里p1->next 怎么理解啊
for(p3 = p1 , p2 = p3 -> next ; p2 ; p2 = p3 -> next) {//这个p2有什么作用,后面这个不是重复了吗?可以省略吗 本帖最后由 jhq999 于 2021-11-8 15:00 编辑
zhenhaowa66 发表于 2021-11-8 14:03
for(p1 = list ; p1 -> next ; p1 = p1 -> next) { //这里p1->next 怎么理解啊
...
第一个p1->next 判断条件,最后一个的next是NULL,就是假退出循环;
p2=p3->next和上面p1->next一样做为是否到了最后的循环条件,而且而循环体里p2和p1重复后,把p3和p2的next联系起来,然后释放p2
jackz007 发表于 2021-11-8 10:40
试试这个代码呢
你这个代码好像还有点问题,我换了数据就行不通,崩了 本帖最后由 jhq999 于 2021-11-8 16:22 编辑
zhenhaowa66 发表于 2021-11-8 15:11
你这个代码好像还有点问题,我换了数据就行不通,崩了
for(p3 = p1 , p2 = p3 -> next ; p3->next ;p2 = p3 -> next)//试试,他没考虑到最后一个重复,这时p3->next=p2->next=NULL,而p2只是释放不为NULL,p2= p3 -> next=NULL再进入循环体必然崩
编程就是不断的调试 本帖最后由 jackz007 于 2021-11-8 17:26 编辑
zhenhaowa66 发表于 2021-11-8 15:11
你这个代码好像还有点问题,我换了数据就行不通,崩了
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data ;
struct node * next ;
} * PLIST ;
void show(PLIST head)
{
if(head) {
for(int c = 0 ; head ; head = head -> next) {
if(c && ! (c % 8)) printf("\n") ;
else if(c) printf(" , ") ;
printf("%5d" , head -> data) ;
c ++ ;
}
} else {
fprintf(stderr , "错误:链表为空!\n") ;
}
printf("\n") ;
}
PLIST add(PLIST * head)
{
PLIST p , p1 , p2 ;
int d ;
if(* head) for(p1 = * head , p2 = NULL ; p1 ; p2 = p1 , p1 = p1 -> next) ;
else p1 = p2 = NULL ;
printf("输入节点数据 :\n ") ;
for(;; p2 = p) {
scanf("%d" , & d) ;
if(d > 0) {
if(p = (PLIST) malloc(sizeof(struct node))) {
p -> data = d ;
p -> next = NULL ;
if(p2) p2 -> next = p ;
else * head = p ;
} else {
fprintf(stderr , "内存分配失败!\n") ;
* head = p ;
break ;
}
} else {
break ;
}
}
return * head ;
}
void deleteIdentica_ListNode(PLIST list)
{
PLIST p1 , p2 , p3 ;
if(list) {
for(p1 = list ; p1 && p1 -> next ; p1 = p1 -> next) {
for(p3 = p1 , p2 = p3 -> next ; p2 ; p2 = p3 -> next) {
if(p2 -> data == p1 -> data) {
p3 -> next = p2 -> next;
free(p2) ;
} else {
p3 = p2 ;
}
}
}
} else {
fprintf(stderr , "Error : Empty Data Link !\n" ) ;
}
}
void destroy(PLIST head)
{
PLIST p1 , p2 ;
for(p2 = NULL , p1 = head ; p1 ; p1 = p2) {
p2 = p1 -> next ;
free(p1) ;
}
}
int main(void)
{
PLIST head = NULL ;
add(& head) ;
printf("\n") ;
printf("去除重复前:\n") ;
show(head) ;
deleteIdentica_ListNode(head) ;
printf("去除重复后:\n") ;
show(head) ;
destroy(head) ;
}
编译、运行实况:
D:\0002.Exercise\C>g++ -o x x.c
D:\0002.Exercise\C>x
输入节点数据 :
14592 1774 12583 32215 26879 1688 2288 2288 2288 2288 2288 2288 2288 2288 2288
2288 8259 857 4989 11010 0
去除重复前:
14592 ,1774 , 12583 , 32215 , 26879 ,1688 ,2288 ,2288
2288 ,2288 ,2288 ,2288 ,2288 ,2288 ,2288 ,2288
8259 , 857 ,4989 , 11010
去除重复后:
14592 ,1774 , 12583 , 32215 , 26879 ,1688 ,2288 ,8259
857 ,4989 , 11010
D:\0002.Exercise\C>
这个代码在输入的节点数据值小于 1 时结束输入。
用这个代码测试你的数据,我倒是想知道,什么样的数据能让它崩溃! jackz007 发表于 2021-11-8 16:35
编译、运行实况:
这个代码在输入的节点数据值小于 1 时结束输入。
谢谢你了,我开始测试了个极端的例子,山到只剩最后一个才崩掉的,只要有2个节点就不会崩 本帖最后由 jackz007 于 2021-11-8 16:55 编辑
zhenhaowa66 发表于 2021-11-8 16:42
谢谢你了,我开始测试了个极端的例子,山到只剩最后一个才崩掉的,只要有2个节点就不会崩
for(p1 = list ; p1 -> next ; p1 = p1 -> next) {
for(p3 = p1 , p2 = p3 -> next ; p2 ; p2 = p3 -> next) {
第一句位于两个分号中间的 p1 -> next 等价于 p1 -> next != NULL,下面 for 语句中位于两个分号中间的 p2 同样是这个意思。
指针的 NULL 就是指针 0 值,对应的逻辑值为 false。只要指针不是 NULL,就一定是 true。 本帖最后由 jhq999 于 2021-11-8 17:05 编辑
jackz007 发表于 2021-11-8 16:52
第一句位于两个分号中间的 p1 -> next 等价于 p1 -> next != NULL,下面 for 语句中位于两个 ...
14592 1774 12583 32215 26879 1688 2288 2288 2288 2288 2288 2288 2288 2288 2288
2288 8259 857 4989 11010 11010 0
for(p1 = list ; p1; p1 = p1 -> next) {
for(p3 = p1 , p2 = p3 -> next ; p3->next ; p2 = p3 -> next)
{
.........
}
} jhq999 发表于 2021-11-8 17:04
14592 1774 12583 32215 26879 1688 2288 2288 2288 2288 2288 2288 2288 2288 2288
2288 8259 857 49 ...
2、8 楼的代码已经修正,请你再测。 zhenhaowa66 发表于 2021-11-8 16:42
谢谢你了,我开始测试了个极端的例子,山到只剩最后一个才崩掉的,只要有2个节点就不会崩
2、8 楼的代码已经修改了,就用你先前的极端例子测。 本帖最后由 jhq999 于 2021-11-8 17:42 编辑
jackz007 发表于 2021-11-8 17:27
2、8 楼的代码已经修正,请你再测。
献丑了,基本功比较差,居然以为赋初值后先条件后运算{:5_96:} jackz007 发表于 2021-11-8 17:33
2、8 楼的代码已经修改了,就用你先前的极端例子测。
{:5_95:}厉害了!确实是这样怎么搞都行{:5_95:} jackz007 发表于 2021-11-8 16:52
第一句位于两个分号中间的 p1 -> next 等价于 p1 -> next != NULL,下面 for 语句中位于两个 ...
感谢耐心讲解!现在基本看明白了,之前没要见过这样的for语句,不知道还可以这样搞for语句{:10_265:} jackz007 发表于 2021-11-8 17:27
2、8 楼的代码已经修正,请你再测。
现在我也搞清楚了我的代码为什么删不干净就是不应该j=i+1;直接j=0;就没有问题了
就用排序里面的冒泡法就可以解决了,
void deleteIdentica_ListNode(PLIST list) {//删除重复数据
if (list == NULL) {
perror("链表地址是NULL,即将退出程序!\n");
exit(-1);
}
PNODE pFirst = list->Head.next; //指向链表第一个有真实数据的节点
PNODE pSecond = pFirst->next; //指向链表第二个有真实数据的节点
PNODE delete = NULL; //指向待删除的重复数据的节点
for (int i = 0; i < list->M_size - 1; i++) {
for (int j = 0; j < list->M_size - i; j++); {
if (pFirst->data == pSecond->data) {
delete = pSecond;
pFirst->next = pSecond->next;
free(delete);
pSecond = pFirst->next;
}
}
}
return;
}
页:
[1]