最近偶尔看到一篇关于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说一般操作系统核心部分用这种方式。

删除链表之two star programming的更多相关文章

  1. [LeetCode] Delete Node in a Linked List 删除链表的节点

    Write a function to delete a node (except the tail) in a singly linked list, given only access to th ...

  2. 剑指Offer面试题:12.在O(1)时间删除链表结点

    一.题目:在O(1)时间删除链表结点 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点. 原文采用的是C/C++,这里采用C#,节点定义如下: public class ...

  3. 【编程题目】在 O(1)时间内删除链表结点

    60.在 O(1)时间内删除链表结点(链表.算法).题目:给定链表的头指针和一个结点指针,在 O(1)时间删除该结点.链表结点的定义如下:struct ListNode{int m_nKey;List ...

  4. [CareerCup] 2.3 Delete Node in a Linked List 删除链表的节点

    2.3 Implement an algorithm to delete a node in the middle of a singly linked list, given only access ...

  5. 链表:删除链表中重复的结点(java实现)

    题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  6. lintcode:删除链表中指定元素

    题目 删除链表中等于给定值val的所有节点. 样例 给出链表 1->2->3->3->4->5->3, 和 val = 3, 你需要返回删除3之后的链表:1-> ...

  7. 【面试题013】在O(1)时间删除链表结点

    [面试题013]在O(1)时间删除链表结点  我们要删除结点i,我们可以把结点i的下一个结点j的内容复制到结点i,然后呢把结点i的指针指向结点j的下一个结点.然后在删除结点j. 1.如果结点i位于链表 ...

  8. lintcode:在O(1)时间复杂度删除链表节点

    题目: 在O(1)时间复杂度删除链表节点 给定一个单链表中的表头和一个等待被删除的节点(非表头或表尾).请在在O(1)时间复杂度删除该链表节点.并在删除该节点后,返回表头. 样例 给定 1->2 ...

  9. lintcode:Remove Nth Node From End of Lis 删除链表中倒数第n个节点

    题目: 删除链表中倒数第n个节点 给定一个链表,删除链表中倒数第n个节点,返回链表的头节点.  样例 给出链表1->2->3->4->5->null和 n = 2. 删除 ...

随机推荐

  1. mount: /dev/sdb already mounted or /sheepdog1 busy(multipath,wwid,uuid,udev)

    正常处理逻辑: 先umount /dev/sdb或是umount /backup如果还是显示的busy,你试试下面的方法fuser -m /dev/sdb查看一下是否sdb1正在被使用,或是有进程正在 ...

  2. jquery 操作单选按钮

    <input type="radio" name="sex" value="男" />男 <input type=&quo ...

  3. C#如何:启用和禁用自动绑定重定向 (微软)

    https://msdn.microsoft.com/zh-cn/library/2fc472t2.aspx 如何:启用和禁用自动绑定重定向 .NET Framework (current versi ...

  4. ASP.NET Redis 开发 入门

    ASP.NET Redis 开发   文件并发(日志处理)--队列--Redis+Log4Net Redis简介 Redis是一个开源的,使用C语言编写,面向“键/值”对类型数据的分布式NoSQL数据 ...

  5. HTTP客户端之使用request方法向其他网站请求数据

    在node中,可以很轻松的向任何网站发送请求并读取该网站的响应数据. var req=http.request(options,callback); options是一个字符串或者是对象.如果是字符串 ...

  6. 安装FFmpeg3.0.9

    //静态版的 FFmpeg Static Builds   release: 3.3.3 https://www.johnvansickle.com/ffmpeg/ ffmpeg-release-64 ...

  7. VNC跨平台远程桌面的安装与使用

    1.安装:yum install tigervnc-server -y 2.设置自启动: chkconfig vncserver on 3.配置文件:vim /etc/sysconfig/vncser ...

  8. xhtml和html的区别

    1.XHTML要求正确嵌套 错误:<p>XHTML文档<strong>与HTML的主要区别</p></strong> 正确:<p>XHTML ...

  9. canvas绘制圆弧

    canvas绘制圆弧 方法 anticlockwise为true表示逆时针,默认为顺时针 角度都传的是弧度(弧度 = (Math.PI/180)*角度) arc(x, y, radius, start ...

  10. svn使用常用错误

    描述 :SVN更新提交显示文件被锁异常: Working copy XXXXXXXX locked Please execute "Cleanup" command 原因 : 待查 ...