1. 程式人生 > >連結串列面試題 ---- 複雜連結串列的複製

連結串列面試題 ---- 複雜連結串列的複製

一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的一個隨機結點或者NULL,題目要求實現複製這個連結串列,返回複製後的新連結串列
如圖所示:
這裡寫圖片描述
1.先將單鏈表複製,如下圖
這裡寫圖片描述
2.找複雜指標,對新節點複雜指標賦值,如下圖

這裡寫圖片描述

while (pPre)
    {
        pCur = pPre->pNext;
        if (NULL == pPre->pRandom)
            pCur->pRandom = NULL;
        else
            pCur->
pRandom = pPre->pRandom->pNext; pPre = pCur->pNext; }

3.拆結點,如下圖
這裡寫圖片描述

pPre = p1;
    Node* pPre2 = pPre->pNext;
    pCur = pPre->pNext;
    while (pCur->pNext)
    {
        pPre->pNext = pCur->pNext;
        pPre = pCur->pNext;
        pCur->pNext = pPre->
pNext; pCur = pCur->pNext; }

程式碼如下:

//結構體
typedef int DataType;

typedef struct ListNode
{
    struct ListNode* pNext;
    struct ListNode* pRandom;
    DataType data;
}Node;
Node* BuyNode1(DataType d)
{
    Node* NewNode = (Node*)malloc(sizeof(Node));
    if (NewNode)
    {
        NewNode->
data = d; NewNode->pNext = NULL; NewNode->pRandom = NULL; return NewNode; } else { perror("malloc::BuyNode"); return NULL; } } Node* CopyComplexLinkList(Node* p1)//複製複雜連結串列 { Node* pPre = p1; Node* NewNode = NULL; Node* pCur = NULL; //在原連結串列每個節點後與此節點相同的新節點 while (pPre) { NewNode = BuyNode1(pPre->data); NewNode->pNext = pPre->pNext; pPre->pNext = NewNode; pPre = NewNode->pNext; } //給新結點隨機指標域賦值 pPre = p1; while (pPre) { pCur = pPre->pNext; if (NULL == pPre->pRandom) pCur->pRandom = NULL; else pCur->pRandom = pPre->pRandom->pNext; pPre = pCur->pNext; } //將新結點拆下來 pPre = p1; Node* pPre2 = pPre->pNext; pCur = pPre->pNext; while (pCur->pNext) { pPre->pNext = pCur->pNext; pPre = pCur->pNext; pCur->pNext = pPre->pNext; pCur = pCur->pNext; } return pPre2; }
//test.c

void ComplexLinkList_test()
{
    Node node1, node2, node3, node4;
    node4.data = 4;
    node4.pNext = NULL;
    node4.pRandom = NULL;

    node3.data = 3;
    node3.pNext = &node4;
    node3.pRandom = &node3;

    node2.data = 2;
    node2.pNext = &node3;
    node2.pRandom = &node1;


    node1.data = 1;
    node1.pNext = &node2;
    node1.pRandom = &node3;



    Node* ret = CopyComplexLinkList(&node1);

}

相關推薦

連結串列試題 ---- 複雜連結串列複製

一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的一個隨機結點或者NULL,題目要求實現複製這個連結串列,返回複製後的新連結串列 如圖所示: 1.先將單鏈表複製,如下圖 2.找複雜指標,對新節點複

連結串列試題集合

  連結串列面試題: 1. 比較順序表和連結串列的優缺點,說說它們分別在什麼場景下使用? 順序表一般用於查詢,可隨機訪問; 連結串列一般用於增刪改,不可隨機訪問; 如果資料元素不多,兩種方式沒有太大的差別 如果資料元素不定,建議使用連結串列 順序表

連結串列試題C++

注意頭結點的處理,如果倒敘記得將新的尾節點指向空。 示例一 給定一個整數num,如何在節點值有序的連結串列中插入一個節點值為num的節點,並且保證這個單鏈表依然有序。 #include<iostream> #include<thread> using

單鏈表的基本操作及連結串列試題

單鏈表的基本操作及連結串列面試題 程式程式碼如下: LinkList.h #ifndef __LINKLIST_H__ #define __LINKLIST_H__ #include <stdio.h> #include <stdlib.

連結串列試題----約瑟夫環相關

約瑟夫環相關連結串列面試題 繼上篇部落格之------------ 什麼是約瑟夫環 約瑟夫環 判斷是否成環 求環的長度 環的入口點

一文搞定連結串列試題系列之二 —— Leetcode234. Palindrome Linked List迴文連結串列\

連結串列薈萃二: 迴文連結串列 列表解法 迴文連結串列 題目:迴文連結串列給定一個連結串列,判斷該連結串列是否是迴文連結串列,要求O(n)時間複雜度,O(1)空間複雜度。 Given a singly linked

試題18——連結串列和陣列有什麼區別

陣列和連結串列有以下不同: (1)儲存形式:陣列是一塊連續的空間,宣告時就要確定長度。連結串列是一塊可不連續的動態空間,長度可變,每個節點要儲存相鄰結點指標; (2)資料查詢:陣列的線性查詢速度快,查詢操作直接使用偏移地址。連結串列需要按順序檢索結點,效率低; (3)資料插入或刪除:連結串列

連結串列試題

關於連結串列已經學了有一段時間了,今天抽空進行了整理,列出來常見的有關連結串列的面試題,以下想法如有瑕疵望批評指出,希望能給初學者帶來一點參考和價值 從尾到頭列印單鏈表 遞迴列印 // 1、從尾到頭列印單鏈表 遞迴 void ListReversePrint(ListN

leetcode 騰訊筆試試題連結串列題目總結(持續更新。。。)

一、合併兩個有序連結串列(簡單) 將兩個有序連結串列合併為一個新的有序連結串列並返回。新連結串列是通過拼接給定的兩個連結串列的所有節點組成的。  示例: 輸入:1->2->4, 1->3->4 輸出:1->1->2->3-&

試題連結串列、棧和佇列

1.順序儲存結構 順序儲存結構,即陣列。優點:節省儲存空間,隨機存取表中元素;缺點 :插入和刪除操作需要移動元素 順序儲存結構的插入與刪除操作程式碼實現 public void insert(int data){ if (le

連結串列試題】【進階】

1、查詢倒數第 k 個連結串列 題目描述:給定一個單向連結串列 List ,要你設計演算法找出倒數第 K 個結點並列印 struct ListNode { DataType m_Value; ListNode* m_pNext; }; ListNode* FindKt

【資料結構】連結串列試題升級版

1、複雜連結串列的複製 複雜連結串列 一個連結串列的每個結點,有一個next指標指向下一個結點,還有一個random指標指向這個連結串列中的隨機一個結點或者NULL。 現在要求複製這個連結串列,並返回複製後的新連結串列。 思路如下: 複雜連結串列的資料型別: typedef str

【資料結構】連結串列試題

1、倒序列印連結串列 (1)非遞迴方式 程式碼如下: void ReversePrint(ListNode **pFirst) { ListNode *last = NULL; ListNode *cur = NULL; assert(*pFirst != NULL); w

連結串列試題程式碼總結(java)

這是原文連結:http://www.jianshu.com/p/a64d1ef95980 最近總結了一下資料結構和演算法的題目,這是第二篇文章,關於連結串列的,第一篇文章關於二叉樹的參見 廢話少說,上鍊表的資料結構 class ListNode { ListNode ne

leetcode 經典試題連結串列 (2. 兩數相加)

兩數相加 給出兩個 非空 的連結串列用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式儲存的,並且它們的每個節點只能儲存 單位 數字。 如果,我們將這兩個數起來相加起來,則會返回出一個新的連結串列來表示它們的和。 您可以假設除了數字 0 之外,這兩

leetcode 經典試題連結串列(19. 刪除連結串列的倒數第N個節點)

刪除連結串列的倒數第N個節點 給定一個連結串列,刪除連結串列的倒數第 n 個節點,並且返回連結串列的頭結點。 示例: 給定一個連結串列: 1->2->3->4->5, 和 n = 2. 當刪除了倒數第二個節點後,連結串列變為 1->

連結串列試題:返回倒數第k個節點

題目來源:劍指offer 方法一: 首先我們先得出連結串列一共有多少個節點標記為count個,然後正數第count-k+1個就是倒數第k個節點,迴圈得到就可以。 程式碼: class Solution { public: ListNode*

連結串列試題】合併兩個有序連結串列, 合併後依然有序

程式碼 // 合併兩個有序連結串列 SListNode * MergeOrderedList(SListNode *p1First, SListNode *p2First) { SListNode*

連結串列試題之合併兩個有序連結串列

關於合併兩個有序的連結串列,假定該連結串列為升序排列,排列後的新表依舊升序。以下提供兩種方法進行排列。 建立新節點為空,依次後續插入法 Node* MergeTwoList1(N

連結串列試題小結(待完成)

以下程式碼使用的公共結構: 連結串列節點: struct ListNode { int data; ListNode *next; }; 輔助函式: //make a list ListNode *makeList(int *arr, int n) { if(a