删除链表之two star programming
最近偶尔看到一篇关于Linus Torvalds的访问,大神说大部分人都不理解指针。假设被要求写一段链表删除节点的程序,大多数的做法都是跟踪两个指针,当前指针cur和其父节点pre,这种实现很容易理解,但是并没有用到指针的精髓。
Linus是怎么写的呢,且看源代码
//链表之two star programming #include <stdio.h> typedef struct node { int value; struct node *next; }listNode; listNode *insert(listNode *head, int value) { listNode *newNode = new listNode; newNode->value = value; newNode->next = head; return newNode; } void erase(listNode **head_in, int value) { listNode **cur = head_in; while (*cur) { listNode *p = *cur; if (p->value == value) { *cur = p->next; delete p; } else { cur = &(p->next); } } //return head; } void printList(listNode *head) { listNode *p = head; while(p) { printf("%d ", p->value); p = p->next; } printf("\n"); } int main() { listNode *head = NULL; int select, a; do { printf("请输入选择 1--插入, 2--删除, 3--输出,其他跳出\n"); scanf("%d", &select); if(select == 1) { printf("输入将要插入的值, -1表示结束\n"); while(scanf("%d", &a), a != -1) { head = insert(head, a); } } else if(select == 2) { printf("输入将要删除的值, -1表示结束\n"); while(scanf("%d", &a), a != -1) { erase(&head, a); } } else if(select == 3) { printList(head); } else break; } while (1); getchar(); return 0; }
运行结果
在链表的删除节点函数earse()中,并不是把头结点指针head作为参数传入,而是传入指针head的引用,小雨来分析一下运行过程,直接上图说明
可以看出cur的移动比较有意思,它是沿着节点之间的指针移动的,在这里,我们也可以把指针当成一种特殊的节点。
当然现在并不提倡这种编程风格,虽然看起来很简洁,但是太晦涩,不能让人一眼看懂,Linus说一般操作系统核心部分用这种方式。