什么是復雜鏈表?
復雜鏈表指的是一個鏈表有若干個結點,每個結點有一個數據域用于存放數據,還有兩個指針域,其中一個指向下一個節點,還有一個隨機指向當前復雜鏈表中的任意一個節點或者是一個空結點。今天我們要實現的就是對這樣一個復雜鏈表復制產生一個新的復雜鏈表。
復雜鏈表的數據結構如下:
typedef int DataType; //數據域的類型//復雜鏈表的數據結構typedef struct ComplexNode{DataType _data ; // 數據struct ComplexNode * _next; // 指向下個節點的指針struct ComplexNode * _random; // 指向隨機節點(可以是鏈表中的任意節點 or 空)}ComplexNode;
上圖就是一個復雜鏈表的例子,那么我們應該如何實現復雜鏈表的復制呢?
1、首先我們應該根據已有的復雜鏈表創建一條新的復雜鏈表,但是這個新的復雜鏈表的所有的結點的random指針都指向空,這樣是很好實現的,相當于我們創建了一條簡單的單鏈表(newlist),我們要復制的鏈表不妨稱之為oldlist。
2、接下來我們應該把新創建的這條復雜鏈表(newlist)與已有的復雜鏈表(oldlist)合并成如下的形式:
在這種情況下我們已經把兩條復雜鏈表合并成了一條鏈表(稱之為linklist),通過對這條鏈表(linklist)的觀察,我們可以發現合并的鏈表(linklist)中屬于newlist的結點pnew的上一個結點pold(屬于oldlist的結點)的random指針所指向的結點的next指針就應該是pnew結點的randow指針所指向的結點。
這樣我們讓pold和pnew指針一直往后走最后就可以實現對所有屬于新創建的復雜鏈表(newlist)的random指針指向相應的結點的操作。構成的復雜鏈表如下圖
在完成以上的步驟之后我們所要做的工作就很簡單了,我們只要把這一條鏈表linklist分開成我們的newlist鏈表和oldlist鏈表就可以了。
這樣我們就完美的完成了復雜鏈表的復制工作下面就是具體實現的代碼:
頭文件complexnode.h:
#ifndef __COMPLEX__NODE__H__#define __COMPLEX__NODE__H__//包含頭文件#include <stdio.h>#include<stdlib.h>#include <assert.h>typedef int DataType; //數據域的類型//復雜鏈表的數據結構typedef struct ComplexNode{DataType _data ; // 數據struct ComplexNode * _next; // 指向下個節點的指針struct ComplexNode * _random; // 指向隨機節點(可以是鏈表中的任意節點 or 空)}ComplexNode; //創建一個復雜鏈表的結點ComplexNode * BuyComplexNode(DataType x);//打印復雜的單鏈表void Display(const ComplexNode * cplist);//復雜鏈表的復制ComplexNode * CopyComplexNode(ComplexNode * cplist); #endif//__COMPLEX__NODE__H__
具體功能實現complexnode.c
#include "complexnode.h" //創建一個復雜鏈表的結點ComplexNode * BuyComplexNode(DataType x){ComplexNode *cnode = (ComplexNode *)malloc(sizeof(ComplexNode));if(cnode == NULL)//創建失敗{perror("BuyComplexNode()::malloc");return NULL;}//創建成功cnode->_data = x;cnode->_next = NULL;cnode->_random = NULL;return cnode;} //打印復雜的單鏈表void Display(const ComplexNode * cplist){ComplexNode *pnode = cplist;while (pnode){printf("%d::%d -->",pnode->_data,pnode->_random->_data);pnode = pnode->_next;}printf("over/n");}//復雜鏈表的復制ComplexNode * CopyComplexNode(ComplexNode * cplist){ComplexNode * pold = NULL;ComplexNode * pnew = NULL;ComplexNode * newlist = NULL;//指向新的復雜鏈表的頭結點的指針pold = cplist;//創建一條新的復雜鏈表while(pold != NULL){ComplexNode * new_node = BuyComplexNode(pold->_data);if(newlist == NULL)//當新的復雜鏈表中沒有結點時{newlist = new_node;}else//當新的復雜鏈表有結點時{ComplexNode * node = newlist;while(node->_next != NULL)//找到最后一個結點{node = node->_next;}node->_next = new_node;//插入新的結點}pold = pold->_next; }//創建新的復雜鏈表結束 //合并兩條復雜鏈表pold = cplist;pnew = newlist;while (pold){ComplexNode * curold = NULL;ComplexNode * curnew = NULL;curold = pold->_next;curnew = pnew->_next;if(pold->_next == NULL){pold->_next = pnew;pold = curold;pnew = curnew;break;}pold->_next = pnew;pnew->_next = curold;pold = curold;pnew = curnew;}//合并兩條復雜鏈表結束 //讓新創建的那條復雜鏈表上的所有結點的random指針指向相應的結點pold = cplist;pnew = newlist;while (pnew){pnew->_random = pold->_random->_next;pold = pnew->_next;if(pold == NULL)//這是pnew的_next指針已經指向空{break;}pnew = pold->_next;}//結束 //分離合并后的復雜鏈表pold = cplist;pnew = newlist;while (pold){ComplexNode * curold = NULL;ComplexNode * curnew = NULL;if(pnew->_next == NULL)//已經分離完成{pold->_next = NULL;pnew->_next = NULL;break; }curold = pold->_next->_next;curnew = pnew->_next->_next; pold->_next = curold;pnew->_next = curnew;pold = curold;pnew = curnew;}//分離合并的復雜鏈表結束 return newlist;}測試代碼test.c:#include "complexnode.h"http:////復雜鏈表的復制。?個鏈表的每個節點,有?個指向next指針指向下?個節//點,還有?個random指針指向這個鏈表中的?個隨機節點或者NULL,現在要//求實現復制這個鏈表,返回復制后的新鏈表。//ps: 復雜鏈表的結構 void test(){ComplexNode * cplist;ComplexNode * copylist;ComplexNode * node1;ComplexNode * node2;ComplexNode * node3;ComplexNode * node4;cplist = BuyComplexNode(1);node1 = BuyComplexNode(2);node2 = BuyComplexNode(3);node3 = BuyComplexNode(4);node4 = BuyComplexNode(5);cplist->_next = node1;node1->_next = node2;node2->_next = node3;node3->_next = node4;cplist->_random = node3;node1->_random = node4;node2->_random = cplist;node3->_random = node1;node4->_random = node2;Display(cplist);copylist = CopyComplexNode(cplist);Display(copylist);}int main(){test();return 0;}
程序的運行結果如下圖:
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。
新聞熱點
疑難解答
圖片精選