复杂链表的复制(C/C++)

常见的面试题,思路:

<span style="font-size:18px;">/* 链表结点结构 */
struct mylist {
    int data;
    mylist* middle; // point to arbitrary elem of this list( maybe to itself )
    mylist* next; // point to next elem
};</span>

1)在原链表的每个节点后面new一个一样的节点,并链接。这样原链表就变成双倍长,每个节点重复出现一次。即1->2->3变成1->(1)->2->(2)-3->(3)。

括号表示新链表的节点。

2)设置新链表节点的middle指针。

3)断开两个链表,返回新链表。

#include 
   
   
    
    
#include 
    
    
     
     
using namespace std;

/* 链表结点结构 */
struct mylist {
    int data;
    mylist* middle; // point to arbitrary elem of this list( maybe to itself )
    mylist* next; // point to next elem
};

void printList( mylist* pHead ) {
    while( pHead ) {
        printf("%d\n", pHead ->data );
        printf("\t%d\n", pHead ->middle ->data );
        pHead = pHead ->next;
    }
}

mylist* copyMylist( mylist* pMylist ) {
    if( pMylist == NULL )
        return NULL;

    mylist* p = pMylist;
    mylist* pRet; /* 保存复制出来的链表第一个节点 */
    
    /* 1) 遍历原链表,在每个节点后面产生并链接与原来相同(data)的节点。*/
    /* 运行完后链表的节点重复出现一次,此时每个第二个重复的节点构成了新链表 */
    while( p ) {
        mylist* pNew = new mylist;
        pNew ->data = p ->data;
        pNew ->next = p ->next;
        pNew ->middle = NULL;
        p ->next = pNew;
        p = pNew ->next;
    }
    pRet = pMylist ->next; /* 设置新链表第一个节点 */
    
    p = pMylist;
    mylist* q = p ->next;
    
    /* 2) 设置新链表节点的middle指针 */
    while( p ) {
        q ->middle = p ->middle ->next;
        p = q ->next;
        if( p )
            q = p ->next;
    }

    /* 3) 分开两个链表,即重新设置新旧链表每个节点的next域 */
    p = pMylist;
    q = p ->next;
    mylist* pNext;
    mylist* qNext;
    while( p ->next ) {
        if( p ->next ->next == NULL ) // 易漏!判断当前节点p是否是原链表的最后一个节点
        {
            p ->next = NULL;
            break;
        }
        pNext = q ->next;
        qNext = pNext ->next;

        p ->next = pNext;
        q ->next = qNext;

        p = pNext;
        q = qNext;
    }

    return pRet;
}

int main()
{
    mylist a,b,c,d;
    a.data = 1, b.data = 2, c.data = 3, d.data = 4;
    a.next = &b, b.next = &c, c.next = &d, d.next = NULL;
    a.middle = &c, b.middle = &d, c.middle = &c, d.middle = &b;
    
    mylist* p = copyMylist( &a );
    printf("original list a:\n");
    printList( &a );

    printf("copied list: \n");
    printList( p) ;

    return 0;
}

    
    
   
   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值