Remove duplicates in linked list before adding - C
My question is how to remove duplicates from a linked list. But I want to do this before adding to the linked list.
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;
}
My problem is keySearch. I don’t know what’s wrong? Or is there another way to do it.
a source to share
In your code, you have 2 comments where you expect to be called keySearch
. In fact, you only need this in the 1st place - second comment. This is because the first place is where you create the new list, so of course there is nothing in it that you need to worry about.
In the second case, you want to call this method keySearch
. There are 3 types of methods keySearch
I can think of that would be helpful:
- Call the method
int keySearch(mystr *p, int value)
that looksp
forvalue
and, if found, returnstrue
(non-zero) - Call a method
int keySearch(mystr *p)
that looksp
for any duplicates and removes them. However, this will not be triggered by every addition, and the above implementation assumes this is not what you are trying to do. There is much more to do it anyway. - Call the method
int keySearch(mystr *p)
that loops throughp
to see if the first value is repeated inq
, returningtrue
if so. This seems to be what your method is trying.
Based on the method signature, you are trying to do # 2 or # 3. But both are wrong - they assume that you have already added a duplicate to the list. Instead, you should try to prevent the duplicate from being duplicated. However, the method as it is does not have sufficient information for this. It needs the value of an element that hasn't been added yet.
I would suggest changing the method to the one in # 1 and passing in the value you want to add. If found, return 1. In the method append
, if this function evaluates to 1, do not add anything. Otherwise, add a new item.
int keysearch(struct myStr *p, int value)
{
if(p == NULL) return 0;
// reusing p is fine - it 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;
}
Now when you are about to add an item, first start it using this method. If the method returns 1, leave your method immediately append
- nothing can be done. If it returns 0 then malloc
your new node and set it to the end of the list.
EDIT . The entrepreneurial code might optimize a little so that at each one append
we don't loop through the entire list (one for keySearch
and then one to find the last item to actually add). You can do this by slightly changing 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!
}
a source to share
This looks somewhat dubious:
if(temp->number == key)
{
found = 1;
}
temp = temp->next;
}
return found;
}
Why not just return 1
as soon as tmp->number == key
? There is no reason to continue in the loop (or at least the rest of the code you put in has no reason at all) after a match is found.
Another thing, I think you want to test while (temp->next != NULL)
instead of comparing an integer to NULL, especially before assigning temp
to temp->next
.
You will also want to use something more line by line:
int keysearch (myStr *p, int key)
And ask the caller to pass the value to look for.
a source to share
What do you mean by "your wrong"?
Besides:
First of all. temp-> number is an integer and you can check the next pointer in the while statement.
Secondly. if you assigned temp = p and enter the value p-> number than you check in the while loop, it will always be true for the first iteration.
Thirdly. It can crash if temp is invalid in your while statement.
a source to share