C++深度理解复杂链表的构造复制

#include <iostream>
using namespace std;
#define Default -1
struct Node
{
    int data;
    Node *next;
    Node *other;//这是复杂链表的额外的一个指针,指向一个指定位置的节点。
    Node(int d = int()) :data(d), next(NULL), other(NULL){}
};

class ContexList
{
public:
    ContexList() :first(NULL)
    {}
    void InsertNext(int a[], int n)
    {
        int i = 0;
        Node *p = NULL;
        for (; i < n; i++)
        {
            Node *s = new Node(a[i]);
            if (first == NULL)
            {
                first = s;
                p = s;
            }
            else
            {
                s->next = p->next;
                p->next = s;
                p = s;
            }
        }
        p = first;
        Node *q = NULL;
        while (p != NULL)
        {
            if (p->next != NULL)
            {
                q = p->next->next;
                p->other = q;
                //每次隔两个指针就用other指针连接一次。
                //构造复杂链表的连接。
            }
            p = p->next;
        }
    }
    void Printf()//打印链表。
    {
        Node *p = first;
        while (p != NULL)
        {
            if (p->other != NULL)
            {
                cout << p->data << "->other:" << p->other->data << endl;
            }
            else
            {
                cout << p->data << "->other:" << "NULL" << endl;
                //打印other的值。
            }
            p = p->next;
        }
    }
    friend void Copy(ContexList cl1, ContexList &cl2)
    {

        Node *oldptr = cl1.first;
        if (oldptr == NULL)return;
        Node *newptr = cl2.first;
        Node *p = newptr;
        Node *m = NULL;


        //好吧,为了防止后面连接重复且混乱的问题,我选择
        //先进行拷贝然后再赋值,为啥要这么做呢?这么做的条理
        //更加的清楚,我考虑过从后面往前拷贝,这样不行,因为
        //这不是数组,无法立刻确定前一个位置的值,如果从前面
        //往后的过程并且赋值的话,会导致重复拷贝,拷贝多次的
        //情况。
        while (oldptr != NULL)
        {
            m = oldptr->next;
            Node *s1 = new Node();
            s1->next = m;
            oldptr->next = s1;

            oldptr = m;
        }


        //赋值并且将other指向确定起来。
        oldptr = cl1.first;
        while (oldptr != NULL)
        {
            m = oldptr->next;
            if (oldptr->other != NULL)
                m->other = oldptr->other->next;
            m->data = oldptr->data;
            oldptr = m->next;
        }

        //这里是正真的拆分重组,将cl1链表链表里面
        //复制的一部分节点摘取出来,然后连接到cl2.first
        //中,实现了拆分以及重组,又不影响以前的链表cl1,
        //又创造了一个新的拷贝与原来链表的链表。
        oldptr = cl1.first;
        Node *q = NULL;
        while (oldptr != NULL)
        {
            m = oldptr->next->next;
            q = m;
            if (p == NULL)
            {
                p = oldptr->next;
                newptr = p;
                cl2.first = newptr;
            }
            else
            {
                p->next = oldptr->next;
                p = p->next;
            }
            oldptr->next = m;
            oldptr = m;
        }
    }
private:

    Node *first;

};

int main()
{
    int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    ContexList cl1;
    cl1.InsertNext(a, sizeof(a) / sizeof(int));

    ContexList cl2;
    Copy(cl1, cl2);
    cout << "链表1->cl1:" << endl;
    cl1.Printf();
    cout << "拷贝之后的链表2->cl2:" << endl;
    cl2.Printf();

    return 0;
}

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值