单链表面试(二)复杂链表的拷贝

已知一个链表有数据域,next指针域和随机指针域,其中随机指针域随机指向该链表的任意一节点,要求复制一条相同的链表。
分析如下图:
《单链表面试(二)复杂链表的拷贝》

//.h
#ifndef __COPY_LIST_H__
#define __COPY_LIST_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
typedef  int   Datatype;
typedef struct Node
{
    Datatype data;
    struct Node*next;
    struct Node*prand;
}Node, *pNode, *pList;
//创建一个新链表a1->b1->a2->b2->a3->b3->NULL;
void new_list(pList head);
//给链表b1的随机指针赋值
void copy_prand(pList head);
//分离链表
pNode sever_list(pList head);
//打印链表信息
void display(pList plist);
#endif
//.c
#include"copy_list.h"
//创建一个新链表a1->b1->a2->b2->a3->b3->NULL;
void new_list(pList head)
{
    assert(head);
    pNode temp = NULL;
    while (head != NULL)
    {
        pNode node = (pNode)malloc(sizeof(Node));
        if (node == NULL)
        {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        node->data = head->data;
        node->next = head->next;
        head->next = node;
        head = node->next;
    }
}
//给链表b1的随机指针赋值
void copy_prand(pList head)
{
    assert(head);
    pNode dest_list = head->next;
    pNode src_list = head;
    while (1)
    {
        dest_list->prand = src_list->prand->next;
        src_list = dest_list->next;
        if (dest_list->next == NULL)
            break;
        dest_list = src_list->next;
    }
}
//分离链表
pNode sever_list(pList head)
{
    assert(head);
    //最初的链表
    pList src_list = head;
    //分离后的链表
    pList dest_list = head->next;
    //分离后面链表的尾节点
    pNode dest_tail = dest_list;
    src_list->next = dest_tail->next;
    src_list = src_list->next;
    //每次处理一个节点
    while (1)
    {
        dest_tail->next = src_list->next;
        dest_tail = dest_tail->next;
        //如果已近处理到了原链表的最后一个节点,就结束循环
        if (dest_tail->next == NULL)
        {
            src_list->next = NULL;
            return dest_list;
        }
        src_list->next = dest_tail->next;
        src_list = src_list->next;
    }
    return dest_list;
}

//打印链表信息
void display(pList plist)
{
    while (plist != NULL)
    {
        printf("[%d]-->(%d)-->", plist->data, plist->prand->data);
        plist = plist->next;
    }
    printf("over\n");
}
//.c
#include"copy_list.h"
//复制一个新的链表
pNode copy_list(pList head)
{
    pNode New_list = NULL;
    //利用原来链表生成一个新链表
    new_list(head);
    //给新链表的随机指针域赋值
    copy_prand(head);
    //分离链表得到一个一样的链表
    New_list = sever_list(head);
    return New_list;
}
//开辟节点
pNode MALL(Datatype x)
{
    pNode ret = NULL;
    ret = malloc(sizeof(Node));
    if (ret == NULL)
    {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    memset(ret, 0, sizeof(Node));
    ret->data = x;
    return ret;
}
void test()
{
    pNode NEW_LIS = NULL;
    pNode pndode1 = MALL(1);
    pNode pndode2 = MALL(2);
    pNode pndode3 = MALL(3);
    pNode pndode4 = MALL(4);
    pNode pndode5 = MALL(5);
    //生成链表
    pndode1->next = pndode2;
    pndode2->next = pndode3;
    pndode3->next = pndode4;
    pndode4->next = pndode5;
    pndode5->next = NULL;
    //prand赋值
    pndode1->prand = pndode3;
    pndode2->prand = pndode4;
    pndode3->prand = pndode1;
    pndode4->prand = pndode3;
    pndode5->prand = pndode2;
    //得到一个新的链表
    NEW_LIS = copy_list(pndode1);
    //对比两个链表内容
    display(pndode1);
    display(NEW_LIS);
}
int main()
{
    test();
    system("pause");
    return 0;

}

《单链表面试(二)复杂链表的拷贝》

    原文作者:AI_T
    原文地址: https://blog.csdn.net/love18792838953/article/details/76604888
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞