有一个链表List,其每个节点有2个指针,一个指针next指向链表的下个节点,另一个random随机指向链表中的任一个节点,可能是自己或者为空,写一个程序,要求复制这个链表的结构并分析其复杂性。
List如图一
图一:需要复制的链表
图二:ABCD是原来的链表,A’B’C’D’是复制的链表,第一遍扫描顺序复制next指针,把ABCD的next分别指向A’B’C’D’,将A’的next指针指向B,B’的next指针指向C,依次类推
复制random指针: A’->random=A->random->next
恢复:A->next=A’->next;A’->next=A’->next->next;
上面的图取自http://www.cppblog.com/yuech/archive/2011/04/02/143318.html
程序实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct s_node
{
struct s_node *next;
struct s_node *random;
int key;
}Node;
Node * dupRandList(Node *list)
{
assert(NULL != list);
Node *rethead ,*tmpretlist, *tmplist = list;
Node *retNode;
while(NULL != tmplist)
{
retNode = malloc(sizeof(Node));
assert(NULL != retNode);
retNode->key = tmplist->key;
retNode->next = tmplist->next;
tmplist->next = retNode;
tmplist = retNode->next;
}
tmplist = list;
rethead = list->next;
tmpretlist = rethead;
while(NULL != tmpretlist && NULL != tmpretlist->next)
{
if(NULL != tmplist->random)
tmpretlist->random = tmplist->random->next;
tmplist = tmplist->next->next;
tmpretlist = tmpretlist->next->next;
}
tmplist = list;
tmpretlist = rethead;
while(NULL != tmpretlist && NULL != tmpretlist->next)
{
tmplist->next = tmpretlist->next;
tmpretlist->next = tmpretlist->next->next;
tmplist = tmplist->next;
tmpretlist = tmpretlist->next;
}
return rethead;
}
测试程序
int main()
{
Node *list = NULL, *ret = NULL, *tmplist;
Node *node = NULL;
int i, max = 10;
list = malloc(sizeof(Node));
assert(NULL != list);
list->key = 0;
list->next = NULL;
list->random = NULL;
for(i = 1; i < max; i++)
{
node = malloc(sizeof(Node));
assert(NULL != node);
node->key = i;
node->next = list->next;
node->random = NULL;
list->next = node;
}
ret = dupRandList(list);
while(NULL != ret)
{
printf("%3d",ret->key);
ret = ret->next;
}
printf("\n");
while(NULL != ret)
{
node = ret;
ret = ret->next;
free(node);
}
tmplist = list;
tmplist->random = tmplist->next->next;
tmplist = tmplist->random;
tmplist->random = tmplist->next;
tmplist = tmplist->random->next;
tmplist->random = tmplist;
ret = dupRandList(list);
while(NULL != ret)
{
if(NULL != ret->random)
printf("%3d",ret->random->key);
ret = ret->next;
}
printf("\n");
while(NULL != ret)
{
node = ret;
ret = ret->next;
free(node);
}
ret = list;
while(NULL != ret)
{
node = ret;
ret = ret->next;
free(node);
}
}
程序输出:
[root@localhost pngynghay]# ./test
0 9 8 7 6 5 4 3 2 1
8 7 6
[root@localhost pngynghay]#