复制一个带random指针的链表
一个单链表,其中除了next指针外,还有一个random指针,指向链表中的任意某个元素。
如何复制这样一个链表呢?
通过next来复制一条链是很容易的,问题的难点在于如何恰当地设置新链表中的random指针。从这个目的出发,我们要在旧链表和新链表的对应节点之间建立联系。除了在链表之外来另外开辟空间存储的方法之外,我们可以利用链表中多余的指针来连接起来。
不扯淡了,上代码。这里的只是一种可能,不一定要某个指针一定要某种用途,但是思想是类似的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | #include <cstdio> #include <cstdlib> #include <ctime> #include <cassert> using namespace std; struct Node { int val; struct Node *next; struct Node *random; Node( int val_, Node *next_, Node *random_) : val(val_), next(next_), random(random_) { } Node ( int val_) : val(val_), next(NULL), random(NULL) { } Node () // for the head nodes. : val(-1), next(NULL), random(NULL) { } }; #define NR_NODES 10 // Setup a linked-list with random pointer void setup_random_linked_list( struct Node *head) { Node *curr; Node *all_nodes[NR_NODES]; int i; // allocate all the nodes. for (i = NR_NODES - 1; i >= 0; i--) { curr = new Node(i, head->next, NULL); head->next = curr; all_nodes[i] = curr; } // setup the random pointers in each node. srand ( time (0)); curr = head->next; while (curr) { curr->random = all_nodes[ rand () % NR_NODES]; curr = curr->next; } } // free the list void free_random_linked_list( struct Node *head) { Node *curr, *temp; curr = head->next; while (curr) { temp = curr->next; delete curr; curr = temp; } } void print_random_linked_list( struct Node *head) { Node *curr; curr = head->next; while (curr) { printf ( "%d " , curr->val); curr = curr->next; } printf ( "\n" ); curr = head->next; while (curr) { printf ( "%d " , curr->random->val); curr = curr->next; } printf ( "\n" ); } // copy from list @src to list @dst. void copy_random_linked_list( struct Node *dst, struct Node *src) { // Image that there're 4 parallel lists... Node *curr_src, *curr_dst; // 1, duplicate the list. curr_src = src->next; while (curr_src) { // copy the node curr_dst = new Node(curr_src->val); // 'random' vertically goes down, while 'next' goes up to original's random. curr_dst->next = curr_src->random; curr_src->random = curr_dst; // move forward curr_src = curr_src->next; } // 2, Now that 'random' comes vertically form the original list to the duplicated list, // and that 'next' points to the random node in the old list, // use that to setup the 'random' pointer in the new list. curr_src = src->next; dst->next = curr_src->random; // follow the head node. while (curr_src) { curr_dst = curr_src->random; // setup 'random' relationship via the original list. curr_dst->random = curr_dst->next->random; // move forward curr_src = curr_src->next; } // 3, now the vertical links still exist, and 'next's in the new list point to 'random' // in the original list, go through the lists to repair both. curr_src = src->next; while (curr_src) { curr_dst = curr_src->random; // setup 'next' relationship via the original list. curr_src->random = curr_dst->next; curr_dst->next = curr_src->next ? curr_src->next->random : NULL; // move forward curr_src = curr_src->next; } } int main( int argc, char *argv[]) { Node head, head2; setup_random_linked_list(&head); printf ( "the original list before copying: \n" ); print_random_linked_list(&head); copy_random_linked_list(&head2, &head); printf ( "finished copying random linked list.\n" ); printf ( "the original list after copying: \n" ); print_random_linked_list(&head); printf ( "and the duplicated list: \n" ); print_random_linked_list(&head2); free_random_linked_list(&head); free_random_linked_list(&head2); return 0; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 《HelloGitHub》第 106 期
· 数据库服务器 SQL Server 版本升级公告
· 深入理解Mybatis分库分表执行原理
· 使用 Dify + LLM 构建精确任务处理应用