复制带随机指针的链表

有一个链表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]# 



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值