2012-07-19 62 views
4

我想编写一个函数,它获取指向链表的头的指针,并从列表中删除每个第二个元素的列表。这份名单是类型元素的连接的元件:c中的指针删除链表中每第二个元素的函数

typedef struct element{ 
    int num; 
    struct element* next; 
}element; 

我是新来的所有这些指针运算,所以我不知道我写正确的:

void deletdscnds(element* head) { 
    element* curr; 
    head=head->next; //Skipping the dummy head// 

    while (head!=NULL) { 
     if (head->next==NULL) 
      return; 

      else { 
       curr=head; 
       head=head->next->next; //worst case I'll reach NULL and not a next of a null// 
       curr->next=head; 
      } 
     } 
    } 

我不停地变化着它因为我一直在发现错误。你能指出任何可能的错误吗?

+5

哎呀!在你这样做了一段时间后,你会在泄露的记忆中站立得很深。你还没有删除任何东西......你刚刚失去了它。 – dmckee 2012-07-19 17:29:18

+0

我应该在放手之前使用“免费”功能吗? – Jozef 2012-07-19 17:30:55

+0

在删除curr之前,您必须获取curr-> next的值。 – 2012-07-19 17:31:31

回答

9

如果按照节点对来考虑链表,算法会简单得多。循环的每次迭代都应该处理两个节点 - headhead->next,退出后离开head等于head->next->next。不要忘记删除中间节点也很重要,如果您将其从列表中删除,否则您将看到内存泄漏。

while (head && head->next) { 
    // Store a pointer to the item we're about to cut out 
    element *tmp = head->next; 
    // Skip the item we're cutting out 
    head->next = head->next->next; 
    // Prepare the head for the next iteration 
    head = head->next; 
    // Free the item that's no longer in the list 
    free(tmp); 
} 
1

这可能是最简单的递归方面显现这个问题,像这样:

// outside code calls this function; the other functions are considered private 
void deletdscnds(element* head) { 
    delete_odd(head); 
} 

// for odd-numbered nodes; this won't delete the current node 
void delete_odd(element* node) { 
    if (node == NULL) 
    return; // stop at the end of the list 
    // point this node to the node two after, if such a node exists 
    node->next = delete_even(node->next); 
} 

// for even-numbered nodes; this WILL delete the current node 
void delete_even(element* node) { 
    if (node == NULL) 
    return NULL; // stop at the end of the list 
    // get the next node before you free the current one, so you avoid 
    // accessing memory that has already been freed 
    element* next = node->next; 
    // free the current node, that it's not needed anymore 
    free(node); 
    // repeat the process beginning with the next node 
    delete_odd(next); 
    // since the current node is now deleted, the previous node needs 
    // to know what the next node is so it can link up with it 
    return next; 
} 

对我来说,至少,这有助于澄清需要在每一步做什么。

我不会建议实际使用这种方法,因为在C语言中,递归算法可能会占用大量内存,并导致堆栈溢出,而这些编译器并未优化它们。相反,dasblinkenlight的答案有你应该实际使用的代码。

相关问题