写一个“在双链表里在指定结点前插入结点”的函数,传参传什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Adia
V2EX    Java

写一个“在双链表里在指定结点前插入结点”的函数,传参传什么?

  •  
  •   Adia 2016-08-20 17:48:02 +08:00 4337 次点击
    这是一个创建于 3348 天前的主题,其中的信息可能已经有所发展或是发生改变。

    原帖在这里

    背景:菜鸟一枚,最近在自学数据结构与算法。

    结果碰上这么一个问题,两个答案两个分歧。实在搞不懂,求万大 V 指一条明路。

    14 条回复    2016-08-21 19:05:27 +08:00
    Em5O7B1JGfjQnBry
        1
    Em5O7B1JGfjQnBry  
       2016-08-20 18:55:32 +08:00 via Android
    这个要看你链表是怎么实现的咯。
    比如你可以传一个指向链表的指针 p 和一个指定结点的排在第几位的整数 n ,然后指针顺下去达到结点插入就可以了。
    Em5O7B1JGfjQnBry
        2
    Em5O7B1JGfjQnBry  
       2016-08-20 18:59:56 +08:00 via Android
    没看原帖,尴尬。。。
    danngo2455
        3
    danngo2455  
       2016-08-20 19:08:33 +08:00   2
    同意原帖中的"不能是 Node"这个回答
    接口的设计要和实现解耦, 换言之, 从调用方的角度看, 只需要知道这是一个 List.
    另外, 在指定结点前插入结点其实可以拆分成语义更原子的接口, 一个是 indexOf(item), 返回 item 的下标, 另一个是 insert(index, item), 将元素插入指定下标处.
    aias
        4
    aias  
       2016-08-20 19:56:10 +08:00
    我就过来看一下
    CRVV
        5
    CRVV  
       2016-08-20 20:05:45 +08:00
    这种问题显然没有唯一的正确答案,两种方法都有优缺点

    "不能是 Node" 的理由在 3 楼
    "应该是 Node" 的理由是用 Node 的性能更好
    allanzyne
        6
    allanzyne  
       2016-08-20 20:45:54 +08:00 via Android
    是 c++的话是肯定传递迭代子的……
    Mirana
        7
    Mirana  
       2016-08-20 21:24:09 +08:00
    void insert(Node *t,Node* n){
    t->prev->next=n;
    n->prev=t->prev;
    n->next=t;
    t->prev=n;
    }
    这样?
    allanzyne
        8
    allanzyne  
       2016-08-20 21:31:16 +08:00
    对于一个链表,却使用随机访问,而且是双向链表 = =
    yangff
        9
    yangff  
       2016-08-20 22:17:39 +08:00
    @manong 的那种做法会有一个很严重的偏差…… 值得注意
    比如你现在有两个链表 A , B
    `A.insertBefore(A.find(YYY), B.find(XXX))` (假如说你这个 node 可以被外部访问,也是 @manong 做法 work 的一个基本要求对吧)
    calease
        10
    calease  
       2016-08-21 00:35:40 +08:00
    如果这个链表是直接给人用的那肯定是传 node ,使用者不可能不知道 node 这个类。
    如果是用链表的方式实现一个 List ,给人用 List ,那么上层的 list interface 设计里才会用到二楼的回答。
    starqoq
        11
    starqoq  
       2016-08-21 01:30:53 +08:00
    @Mirana 没有判断 t 是头节点的情况。 t.prev == NULL


    我不会 java ,这是 C++的写法。
    注意结构体里面的 first , last 都要是指针,否则无法表示空链表
    函数将新节点 n 插入 t 之前,如果 t 为 NULL 表明插入到列表尾部。

    链表维护需要小心谨慎,考虑到各种情况,头尾,空链表。注意维护首尾指针。
    删除的时候也是一样。

    void insert(Node *t,Node* n){
    //如果有 size 需要维护
    //size++;

    n->prev = n->next = NULL;
    if (t == NULL) //用 t==NULL 指明插入到列表结尾
    {
    if (last==NULL) //空链表
    first = last = n;
    else //插入到尾部
    {
    last->next = n;
    n->prev = last;
    last = n;
    }
    return ;
    }

    if (t->prev == NULL) // 说明是第一个 也可以用 first == t
    {
    first = n;
    n->next = t;
    t->prev = n ;
    return ;
    }

    //一般情况
    t->prev->next=n;
    n->prev=t->prev;
    n->next=t;
    t->prev=n;
    }
    minami
        12
    minami  
       2016-08-21 03:06:55 +08:00
    其实吧,你这问题根子上是要搞清楚你要“如何定位 node ”,也就是“如何区分两个 node ”,如果你禁止重复的元素,那完全可以传元素值;反过来,你就只能传引用或者其他可以确定 node 的标识符(比如位置,比如 UUID ),这要看你的内部是如何实现的。
    ps :学习就是要多想想,比较各种实现的优劣,这和实际编程不一样,平时是有约定俗成的规范。
    zscself
        13
    zscself  
       2016-08-21 16:31:18 +08:00
    我觉得用 Java 写的话,可以写一个 insertBefore(Node node, Node newNode)再写一个 insertBefore(int i, Node newNode),到时候愿意用哪个用哪个,/抠鼻。严蔚敏那本数据结构是用的后者。
    allanzyne
        14
    allanzyne  
       2016-08-21 19:05:27 +08:00 via Android
    typedef NodeValue int;
    class Iterator;
    class DoubleLinked {
    class Node: Iterator;
    Iterator insertBefore(Iterator& node, NodeValue v);
    }
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1012 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 22:40 PVG 06:40 LAX 15:40 JFK 18:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86