2010-05-15 92 views
2

我的问题是关于从链接列表中删除重复项。但我想在添加到链接列表之前执行此操作。添加之前删除链接列表中的重复项 - C

struct myStr{int number; mystr *next;} 
void append(mystr **q,int item) 
{ 
myStr *temp; 
temp = *q; 
myStr *newone; 
if(*q==NULL)// There should be control of previous elements. Call of keysearch function. 
    { temp = (myStr *)malloc(sizeof(myStr)); 

      temp->number =size; 
      temp->next=NULL; 
      *q=temp; 
    } 
    else //And also here 
    { temp = *q; 
     while(temp->next !=NULL) 
     { temp=temp->next; 
     } 
     newone = (myStr *)malloc(sizeof(myStr)); 
     newone->count = size; 
     newone->next=NULL; 
     temp->next=newone; 

    } 
} 
int keysearch (myStr *p) 
{ 
struct myStr *temp = p; 
int found = 0; 
int key= p->number; 
while (temp->next != NULL) 
{ 
if(temp->number == key) 
    { 
    return 1; 
//break; 
     } 
    temp = temp->next; 
    } 
    return 0; 
    } 

我的问题是在keySearch。我不知道什么是错的?或者有另一种方法来做到这一点。

+1

你是@LuckySlevin? http://stackoverflow.com/questions/2840228的代码在风格和命名约定中看起来与此非常相似。 – Phil 2010-05-15 14:54:27

+0

这看起来可疑类似于这个问题:http://stackoverflow.com/questions/2840228/appending-unique-values-only-in-a-linked-list-in-c - 代码几乎完全相同。很好的尝试改变变量名称。 – interjay 2010-05-15 14:54:55

+1

@菲尔我认为只有几个人在做同样的任务,我们一定会最终看到这一点。 @DesperateCoders - 如果是家庭作业,请将其标记为家庭作业。 – 2010-05-15 14:59:07

回答

0

在代码中,你有2个意见,你希望被调用keySearch。事实上,你只需要一个地方 - 第二个评论。这是因为第一个地方是你创建一个全新列表的地方,所以当然没有什么是你需要担心的。

在第二种情况下,你要调用此方法keySearch。有3种类型的keySearch方法我能想到的,将是有益的:

  1. 调用一个方法int keySearch(mystr *p, int value),看起来通过pvalue,如果找到,返回true(非零数字)
  2. 调用一个方法int keySearch(mystr *p),通过p查找任何重复项并将其删除。但是,这不会在每个追加上被调用,并且上面的实现表明这不是你想要做的。无论如何,做这件事还有很多工作要做。
  3. 调用方法int keySearch(mystr *p),该方法通过p查找q中的第一个值是否重复,如果是,则返回true。看来这是你的方法试图做的。

基于该方法的签名,您正在尝试执行#2或#3。但这两个都是错误的 - 他们假设你已经将副本添加到列表中。你应该做的是试图防止重复被添加到第一个地方。尽管如此,该方法没有足够的信息来做到这一点。它需要尚未添加的元素的值。

我建议将方法更改为#1中的方法,并传入值想要添加。如果找到,则返回1.在append方法中,如果此函数的计算结果为1,则不要追加任何内容。否则附加新元素。

int keysearch(struct myStr *p, int value) 
{ 
    if(p == NULL) return 0; 
    // reusing p is fine - it's a local variable 
    while(p != NULL) 
    { 
     if(p->number == value) return 1; // return if value exists already 
     p = p->next;      // go to next element 
    } 
    return 0; 
} 

现在,当您要添加元素时,请先用此方法运行它。如果方法返回1,则立即保留append方法 - 没有任何事情要做。如果它返回0,则malloc您的新节点并将其设置为列表的末尾。


编辑:一个积极进取的CodeSmith可能要略微优化,使每append我们没有在整个列表(一个用于keySearch做2圈,然后一个找到实际的最后一个元素追加)。你可以通过稍微修改keySearch ...

// returns NULL if p is empty/value exists; otherwise returns the last element 
struct myStr *keysearch(struct myStr *p, int value) 
{ 
    // same logic, different return values; integration into append changes too! 
} 
+0

感谢您的一切。看起来很好。 – DesperateCoders 2010-05-15 16:02:06

+0

很高兴帮助! – Phil 2010-05-16 01:10:49

0

这看起来有点可疑:

if(temp->number == key) 
    { 
    found = 1; 
    } 
temp = temp->next; 
} 
return found; 
} 

为什么不return 1尽快tmp->number == key?一旦找到匹配,没有理由继续循环(或者至少其他代码粘贴不显示任何理由)。

另一件事是,我认为你想测试while (temp->next != NULL),而不是比较一个整数为NULL,特别是在将temp分配到temp->next之前。

你还需要使用的线沿线的东西更多:

int keysearch (myStr *p, int key) 

并有负责将要搜索的值调用者。

+0

哦,对不起,我纠正(temp-> next!= NULL)。并在if中更改返回值,并在最后返回0。但是我在哪里可以在append中调用这个函数?这是值得怀疑的。 – DesperateCoders 2010-05-15 14:59:14

+0

@DesperateCoders - 我不太明白你想问什么?如果这是作业,请发布作业的完整说明,有人可能会帮助你。 – 2010-05-15 15:03:20

+0

我想控制如果添加的元素已经存在于链表中。我想在添加元素之前或之前执行此操作。 – DesperateCoders 2010-05-15 15:08:04

0

你是什么意思的“它的错”?

除此之外:

首先。 temp-> number是一个整数,你可能想要检查while语句中的下一个指针。

二。如果你指定temp = p并且键入了p-> number的值,那么在第一次迭代中,while循环将始终为真。

三。如果temp语句中的temp无效,它可能会导致崩溃。