单链表面试题--复杂链表的复制

关于单链表中复杂单链表的复制问题是比较复杂的了,当我看到这个题,我对于题目就理解了半天,更别说如何下手去分析题目了。
复杂链表结构下
有一个只想下一个数据的指针_next
有一个指针_random指向任意节点(我就对于这句话不怎么理解,指向任意节点,那么怎么创建它的链表啊,蒙了,后来想明白只需要自己指定它的_random, 如果一个测试用例可以跑通了,那么对于其他的任意_random是不是也可以跑通了? 明白了这一点,分析起来就简单多了)

typedef struct ComplexNode
{
    int _data ; // 数据 
    struct ComplexNode * _next; // 指向下一个节点的指针 
    struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空) 
}ComplexNode;

具体分析如下:
1 . 假设创建一个5个节点的链表如下
这里写图片描述
2. 创建复杂链表
这里写图片描述
3. _next节点的复制
这里写图片描述
4. _random 节点的复制
这里写图片描述
5. 链表分离
这里写图片描述
通过分析之后写代码也就不难了

typedef struct ComplexNode
{
    int _data ; // 数据 
    struct ComplexNode * _next; // 指向下一个节点的指针 
    struct ComplexNode * _random; // 指向随机节点(可以是链表中的任意节点 or 空) 
}ComplexNode;

ComplexNode* splitComplexList(ComplexNode * pList);
ComplexNode* BuyComplexNode(int d)
{
    ComplexNode* ptr = (ComplexNode*)malloc(sizeof(ComplexNode));
    if(ptr == NULL){
        perror("malloc");
        exit(1);
    }
    ptr->_data = d;
    ptr->_next = NULL;
    ptr->_random = NULL;
    return ptr;
}

void CopyComplexList(ComplexNode* pList)
{
    ComplexNode* tmp = pList;
    ComplexNode* newList = pList;
    if(pList == NULL || pList->_next == NULL)
        return;
    //插入节点,在每两个节点之间插入一个节点,数据与前一个相同
    while(tmp)
    {
        ComplexNode* next = pList->_next;
        ComplexNode* insert = BuyComplexNode(tmp->_data);
        insert->_next = tmp->_next;
        tmp->_next = insert;
        tmp = insert->_next;

    }
    //复杂链表的复制
    newList = pList;
    while(newList)
    {
        ComplexNode* newcomplexnode = newList->_next;
        if(newList->_random != NULL)
        {
            newcomplexnode->_random = newList->_random->_next;
        }
        newList = newcomplexnode->_next;
    }
}

//链表分离
ComplexNode* splitComplexList(ComplexNode* pList)
{
    ComplexNode* tmp = pList;
    ComplexNode* list =NULL;
    ComplexNode* newlist = NULL;
    if(pList != NULL)
    {
        list = newlist = tmp->_next;
        tmp->_next = list->_next;
        tmp = tmp->_next;
    }
    while(tmp)
    {
        newlist->_next = tmp->_next;
        newlist = newlist->_next;
        tmp->_next = newlist->_next;
        tmp = tmp->_next;
    }
    return list;
}
int main()
{
    //第一步:创建一个五个节点的链表
    ComplexNode* node = NULL;
    ComplexNode* node1 = BuyComplexNode(1);
    ComplexNode* node2 = BuyComplexNode(2);
    ComplexNode* node3 = BuyComplexNode(3);
    ComplexNode* node4 = BuyComplexNode(4);
    ComplexNode* node5 = BuyComplexNode(5);
    node1->_next = node2;
    node2->_next = node3;
    node3->_next = node4;
    node4->_next = node5;
    node5->_next = NULL;
    //创建复杂链表
    node1->_random = node3;
    node2->_random = node1;
    node3->_random = NULL;
    node4->_random = node4;
    node5->_random = node2;

    CopyComplexList(node1);
    /*while(node1)
    {
        printf("%d ", node1->_data);
        node1 = node1->_next;
    }
    node1*/
    node = splitComplexList(node1);
    printf("%d %d", node->_next->_random->_data);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值