Check if two linked lists merge. If so, where?

后端 未结 26 1390
陌清茗
陌清茗 2020-12-07 06:43

This question may be old, but I couldn\'t think of an answer.

Say, there are two lists of different lengths, merging at a point; how do we know wher

26条回答
  •  抹茶落季
    2020-12-07 07:20

    I have tested a merge case on my FC9 x86_64, and print every node address as shown below:

    Head A 0x7fffb2f3c4b0
    0x214f010
    0x214f030
    0x214f050
    0x214f070
    0x214f090
    0x214f0f0
    0x214f110
    0x214f130
    0x214f150
    0x214f170
    
    
    Head B 0x7fffb2f3c4a0
    0x214f0b0
    0x214f0d0
    0x214f0f0
    0x214f110
    0x214f130
    0x214f150
    0x214f170
    

    Note becase I had aligned the node structure, so when malloc() a node, the address is aligned w/ 16 bytes, see the least 4 bits. The least bits are 0s, i.e., 0x0 or 000b. So if your are in the same special case (aligned node address) too, you can use these least 4 bits. For example when travel both lists from head to tail, set 1 or 2 of the 4 bits of the visiting node address, that is, set a flag;

    next_node = node->next;
    node = (struct node*)((unsigned long)node | 0x1UL);
    

    Note above flags won't affect the real node address but only your SAVED node pointer value.

    Once found somebody had set the flag bit(s), then the first found node should be the merge point. after done, you'd restore the node address by clear the flag bits you had set. while an important thing is that you should be careful when iterate (e.g. node = node->next) to do clean. remember you had set flag bits, so do this way

    real_node = (struct node*)((unsigned long)node) & ~0x1UL);
    real_node = real_node->next;
    node = real_node;
    

    Because this proposal will restore the modified node addresses, it could be considered as "no modification".

提交回复
热议问题