码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2015-07-30 21:33:46      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:复杂链表

#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;
}

技术分享

版权声明:本文为博主原创文章,未经博主允许不得转载。

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

标签:复杂链表

原文地址:http://blog.csdn.net/liuhuiyan_2014/article/details/47154891

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!