我正在尝试筛选一个链表。由于我不想更改原始链接列表,所以我想创建一个子链接列表并返回它。
我遇到了麻烦,因为我只知道如何从筛选过程中获得1个节点,但我不知道如何四处移动并将节点从原始链表添加到子链表。
我有一个这样的结构(这表示哈希表中的一个条目(:
typedef struct Entry {
char *word;
int len;
struct Entry *next;
} Entry;
我的filter函数将接收单词长度和原始链表作为参数,然后查找具有相同len值的节点。每当它找到一个具有相同len值的节点时,就会将该节点添加到另一个链表中。最后,它返回新的链表。
struct Entry* filterLen(int len, struct Entry *en) {
struct Entry *temp = (struct Entry *)malloc(sizeof(struct Entry));
while(en->next != NULL) {
if (en->len == len) {
// assign values to temp list
temp->word = en->word;
temp->len = en->len;
temp->next = en;
}
en = en->next; // move through list
}
return temp;
}
Entry* filterLen(int len, Entry *en) {
Entry result = { NULL, 0, NULL };
Entry *curr = &result;
while(en != NULL){
if(en->len == len){
Entry *temp = malloc(sizeof(*temp));
*temp = *en;
temp->next = NULL;
curr = curr->next = temp;
}
en = en->next;
}
return result.next;
}
Entry* filterLen(int len, Entry *en) {
Entry *result = NULL, **temp = &result;
while(en != NULL) {
if (en->len == len) {
// assign values to temp list
*temp = malloc(sizeof(Entry));
(*temp)->word = en->word;
(*temp)->len = en->len;
(*temp)->next = NULL;
temp = &((*temp)->next);
}
en = en->next; // move through list
}
return result;
}
编辑这里似乎是一场竞争,所以:
Entry* filterLen(int len, Entry *en) {
Entry *result, **temp = &result;
for ( ; en; en = en->next) { // Move through list
if (en->len == len) { // Then assign values to temp list
*temp = malloc(sizeof(Entry));
(*temp)->word = en->word; // WARNING str shared with en list!!!
(*temp)->len = en->len;
temp = &((*temp)->next);
}
}
*temp = NULL;
return result;
}
现在,您的筛选函数正在将找到的最后一个节点的内容(包括next
指针(复制到temp
节点中。这将导致函数返回最后一个匹配节点以及列表中该节点之后的任何节点。
您需要做的是在每次找到匹配的节点时创建一个新节点,并将内容复制到该节点。这包括复制字符串,这样您就不必担心可能会双重释放任何内容。
struct Entry* filterLen(int len, struct Entry *en) {
struct Entry *result = NULL, *temp = NULL;
while(en != NULL) {
if (en->len == len) {
// copy node to end of temp list
if (temp == NULL) {
result = malloc(sizeof(struct Entry));
temp = result;
} else {
temp->next = malloc(sizeof(struct Entry));
temp = temp->next;
}
temp->word = strdup(en->word); // Perform a deep copy
temp->len = en->len;
temp->next = NULL;
}
en = en->next; // move through list
}
return result;
}
根据我在你的问题中所理解的,你想要返回一个链接的条目列表,其中len字段等于输入参数。目前,您的代码只存储一个"temp",您需要重新生成一个新列表。
struct Entry* filterLen(int len, struct Entry *en) {
struct Entry *first = NULL;
struct Entry *last = NULL;
while(en != NULL) {
if (en->len == len) {
if(last){
last->next = (struct Entry *)malloc(sizeof(struct Entry));
last = last->next;
} else {
last = (struct Entry *)malloc(sizeof(struct Entry));
first = last;
}
// assign values to temp list
last->word = en->word;
last->len = en->len;
last->next = NULL;
}
en = en->next; // move through list
}
return first;
}