【编程题目】复杂链表的复制☆

76.复杂链表的复制(链表、算法)
题目:有一个复杂链表,其结点除了有一个 m_pNext 指针指向下一个结点外,
还有一个 m_pSibling 指向链表中的任一结点或者 NULL。其结点的 C++定义如下:
struct ComplexNode
{
int m_nValue;
ComplexNode* m_pNext;
ComplexNode* m_pSibling;
};
请完成函数 ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。

思路:先按照m_pNext复制,再依次遍历链表找m_pSibling

#include <stdio.h>
#include <stdlib.h>

typedef struct ComplexNode
{
    int m_nValue;
    ComplexNode* m_pNext;
    ComplexNode* m_pSibling;
}ComplexNode;

ComplexNode*  Clone(ComplexNode* pHead) //完全复制
{
    if (pHead == NULL)
    {
        return NULL;
    }
    //先复制头结点
    ComplexNode* chead = (ComplexNode*)malloc(sizeof(ComplexNode));
    chead->m_nValue = pHead->m_nValue;
    chead->m_pNext = NULL;
    chead->m_pSibling = NULL;

    ComplexNode* x = pHead->m_pNext;
    ComplexNode* y = chead;

    while(x != NULL) //按照next信息先创建所有的点并连接
    {
        y->m_pNext = (ComplexNode*)malloc(sizeof(ComplexNode));
        y->m_pNext->m_nValue = x->m_nValue;
        y->m_pNext->m_pNext = NULL;
        y->m_pNext->m_pSibling = NULL;

        x = x->m_pNext;
        y = y->m_pNext;
    }

    //复制m_pSibling的指向
    x = pHead;
    y = chead;
    while (x != NULL)
    {
        if (x->m_pSibling == NULL)  //空指针直接复制
        {
            y->m_pSibling = NULL;
        }
        else //非空指针 从头查找指向第几个节点
        {
            if (pHead == x->m_pSibling)
            {
                y->m_pSibling = chead;
            }
            else
            {
                ComplexNode * xx = pHead;
                ComplexNode * yy = chead;
                while (xx->m_pNext != x->m_pSibling)
                {
                    xx = xx->m_pNext;
                    yy = yy->m_pNext;
                }
                y->m_pSibling = yy->m_pNext;
            }
        }
        x = x->m_pNext;
        y = y->m_pNext;
    }

    return chead;
}

void createList(ComplexNode* &pHead) //创建并添加next间关系
{
    int data;
    scanf("%d", &data);
    if (data != 0)
    {
        pHead = (ComplexNode*)malloc(sizeof(ComplexNode));
        pHead->m_nValue = data;
        pHead->m_pNext = NULL;
        pHead->m_pSibling = NULL;
        createList(pHead->m_pNext);
    }
}

void addsibling(ComplexNode* pHead) //添加pSibling间关系
{
    int len = 0;
    ComplexNode* x = pHead;
    while (x != NULL)
    {
        len++;
        x = x->m_pNext;
    }

    x = pHead;
    while (x != NULL)
    {
        int n = 0; //数字表示p_Sibling指向链表中的第n个结点
        printf("please input a number between 1 - %d or 0(means NULL)", len);
        scanf("%d", &n);
        if (n == 0)
        {
            x->m_pSibling = NULL;
        }
        else
        {
            ComplexNode* y = pHead;
            n = n - 1;
            while (n != 0)
            {
                y = y->m_pNext;
                n--;
            }
            x->m_pSibling = y;
        }
        x = x->m_pNext;
    }

}

int main()
{
    ComplexNode* pHead = NULL;
    createList(pHead);
    addsibling(pHead);
    ComplexNode* cHead = Clone(pHead);
    return 0;
}

网上看答案 发现自己的方法很复杂,有一种很巧妙的方法:

http://blog.csdn.net/zhaojinjia/article/details/9313275

方法三:

比较巧妙,只需遍历3次链表,时间代价为O(n),空间代价为0,分3步

1:遍历一遍原始链表,复制结点N对应的N‘,将其插入到结点N的后面,如下图所示

2:确定每个m_pSibling指针的指向,只需遍历一遍链表即可确定每个结点的m_pSibling指针的指向,得到如下图结构

3:再次遍历一遍,将原始链表和复制链表分开,奇数为原始链表,偶数为复制链表,得到如下图型

这个网站上的代码可能略有一点问题。

不过知道思路后,写代码就很容易了。

【编程题目】复杂链表的复制☆,布布扣,bubuko.com

时间: 2024-10-26 16:47:28

【编程题目】复杂链表的复制☆的相关文章

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

60.在 O(1)时间内删除链表结点(链表.算法).题目:给定链表的头指针和一个结点指针,在 O(1)时间删除该结点.链表结点的定义如下:struct ListNode{int m_nKey;ListNode* m_pNext;};函数的声明如下:void DeleteNode(ListNode* pListHead, ListNode* pToBeDeleted); 思路:把当前结点的下一个结点的内容复制到当前结点,删除下一结点即可. 注意,链表中只有一个结点时在题目给定的函数声明下无法删除,

【编程题目】编程判断俩个链表是否相交

第 7 题(链表)微软亚院之编程判断俩个链表是否相交给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交.为了简化问题,我们假设俩个链表均不带环.问题扩展:1.如果链表可能有环列?2.如果需要求出俩个链表相交的第一个节点列? 看到这个题目我很困惑.如果链表的结构是下面这个样子 typedef struct ListNode { int m_Value; ListNode * p_Next; }ListNode; 那么一旦有相交,链表的后端就都是一模一样的了啊?因为交叉点只可能有一个

【编程题目】从尾到头输出链表(链表)☆

58.从尾到头输出链表(链表).题目:输入一个链表的头结点,从尾到头反过来输出每个结点的值.链表结点定义如下:struct ListNode{int m_nKey;ListNode* m_pNext;}; 我的思路:用一个数组存起来已有的数字,再反过来输出.缺点是数组大小是确定的 链表长度不能超过数组的大小 /* 58.从尾到头输出链表(链表). 题目:输入一个链表的头结点,从尾到头反过来输出每个结点的值.链表结点定义如下: struct ListNode { int m_nKey; ListN

【目录】编程题目

编程题目 如何对n个数进行排序,要求时间复杂度O(n),空间复杂度O(1) 一个数组是由一个递减数列左移若干位形成的,在这种数组中查找某一个数.☆ 请修改 append 函数,利用这个函数实现两个非降序链表的并集 一串首尾相连的珠子(m 个),有 N 种颜色(N<=10),取出其中一段,要求包含所有 N 中颜色,并使长度最短. 求一个有向连通图的割点,割点的定义是,如果除去此节点和与其相关的边, 有向图不再连通 有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前

【剑指offer】复杂链表的复制

转载请注明出处:http://blog.csdn.net/ns_code/article/details/26154691 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n (1<=n<=1000):n代表将要输入的链表元素的个数.(节点编号从1开始).接下来有n个数,表示链表节点中的值.接下来有n个数Ti,Ti表示第i个节点的另

剑指offer之【复杂链表的复制】

题目: 复杂链表的复制 链接: https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 题目描述: 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为

19--复杂链表的复制。

/* 题目: 复杂链表的复制. struct ComplexListNode { int m_vlaue; ComplexListNode *m_next; ComplexListNode *m_pSibling; }: m_next,连接下一个结点,m_pSibling随便链接结点其他节点. 这样复制结点就有难度,一次遍历明显不可能全部解决. 策略: 第一种方法: 先复制一遍链表,让m_pnext把结点连接起来.第二轮在复制另一个指针,复杂度为O(n*n); 第二种方法: 先复制一遍链表,然后

复杂链表的复制-剑指Offer

复杂链表的复制 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点). 思路 分三步(分而治之) 将链表复制下来追加到每个元素的后面,例如A->A'->B->B'->C->C'... 复制每个元素的random指针 从整体的链表中间隔的取出复制出来的链表 代码 /* public class RandomListNode { int label; RandomListNode next = null; Random

剑指Offer--026-复杂链表的复制

链接 牛客OJ:复杂链表的复制 九度OJ:http://ac.jobdu.com/problem.php?pid=1524 GitHub代码: 026-复杂链表的复制 CSDN题解:剑指Offer–026-复杂链表的复制 牛客OJ 九度OJ CSDN题解 GitHub代码 复杂链表的复制 1524-复杂链表的复制 剑指Offer–026-复杂链表的复制 026-复杂链表的复制 题意 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)