今晚在这里看到一篇文章,http://coolshell.cn/articles/8…,原文给的是代码片段,本着动手实践的原则,另外顺便复习一下链表,写了下代码
#include <stdio.h> #include <stdlib.h> typedef struct _node { int n; struct _node *next; } node; typedef int (* remove_fn)(node const *n); node *create_link(); void destory_link(node *head); void print_link(node *head); int should_remove(node const *n); node *remove_if(node *head, remove_fn should_remove); void remove_if2(node **head, remove_fn should_remove); int main() { node *head = create_link(); print_link(head); //head = remove_if(head, should_remove); remove_if2(&head, should_remove); print_link(head); destory_link(head); return 0; } node *create_link() { node *head = malloc(sizeof(node)); if (head == NULL) { printf("malloc head failed\n"); return NULL; } head->n = 0; head->next = NULL; node *pre = head; for (int i=1; i<10; i++) { node *cur = malloc(sizeof(node)); if (cur == NULL) { printf("malloc node %d failed\n", i); return NULL; } pre->next = cur; cur->n = i; cur->next = NULL; pre = cur; } return head; } void destory_link(node *head) { node *cur = head; while (cur) { node *next = cur->next; free(cur); cur = next; } } void print_link(node *head) { node *cur = head; while (cur) { printf("%d\t", cur->n); cur = cur->next; } printf("\n"); } int should_remove(node const *n) { if (n == NULL) { return 0; } return (n->n)%2 == 0; } node *remove_if(node *head, remove_fn should_remove) { for (node *pre = NULL, *cur = head; cur;) { node * const next = cur->next; if (should_remove(cur)) { if (pre) { pre->next= next; } else { head = next; } free(cur); } else { pre = cur; } cur = next; } return head; } void remove_if2(node **head, remove_fn should_remove) { for (node **cur = head; *cur;) { node *entry = *cur; if (should_remove(entry)) { *cur = entry->next; free(entry); } else { cur = &(entry->next); } } }
编译运行一下
zrj@zrj-desktop:~/c$ gcc -g -std=gnu99 link.c && ./a.out 0 1 2 3 4 5 6 7 8 9 1 3 5 7 9
其实道理不复杂,自己多读两遍代码就懂了,不得不承认这种写法确实很巧妙,而且就可读性来说,其实也没有下降多少