您的位置:首页 > 编程语言 > C语言/C++

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

2015-07-30 19:35 561 查看
#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;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: