劍指Offer 面試題26 複雜鍊錶的複製

2021-06-25 12:40:54 字數 3123 閱讀 6305

/*

複雜鍊錶的複製:

請事先函式complexlistnode* clone(complexlistnode* phead),複製乙個複雜鍊錶。在複雜鍊錶中,每個結點除了有乙個m_pnext指標

指向下乙個結點外,還有乙個m_psibling指向鍊錶中的任意結點或者null。

a->b->c->d->e

兄弟指向"

a指向c

b指向e

d指向b

e,c指向null

分析:難道先複製下乙個節點指標,再複製任意指的節點指標。

分析:假設原始鍊錶中的某個結點n的m_psibling指向結點s,由於s的位置可能在n的前面或者後面,定位s的位置需要從原始

鍊錶的頭結點開始沿著m_pnext經過s步找到結點s,複製鍊錶上節點n'的m_psibling(記為s')離複製鍊錶的頭結點的

距離也是沿著m_pnext指標s步。

因為每個節點定位m_psibling需要o(n),因此時間複雜度是o(n^2)

優化:1:先複製原始鍊錶早上的每個節點n建立n',然後把建立出來的結點用m_pnext連線起來。同時把的配對資訊

放到雜湊表中。

2:設定複製鍊錶上每個節點的m_psibling。如果在原始鍊錶中結點n的m_psibling指向節點s,name複製鍊錶中,對應

的n'應該指向s'。

n個節點的鍊錶需要大小為o(n)的雜湊表,把o(n)的空間換來將時間複雜度從o(n^2)降為o(n)

方法3:

a->a'->b->b'->c->c'->d->d'->e->e'

2:設定複製出來的節點的m_psibling。假設原始鍊錶上的n的m_psibling指向結點s,複製出來的n'是n的m_pnext

指向的節點。s'也是s的m_pnext指向的結點。

a->a'->b->b'->c->c'->d->d'->e->e'

兄弟指向:

a指向c

a'指向c'

b指向e

b'指向e'

d指向b

d'指向b'

起來就是複製出來的鍊錶。

輸入:輸入可能包含多個測試樣例,輸入以eof結束。

對於每個測試案例,輸入的第一行為乙個整數n (1<=n<=1000):n代表將要輸入的鍊錶元素的個數。(節點編號從1開始)。

接下來有n個數,表示鍊錶節點中的值。

接下來有n個數ti,ti表示第i個節點的另乙個指標指向。

ti = 0 表示這個指標為null。

輸出:對應每個測試案例,

輸出n行,每行有二個數,第乙個代表當前節點值,第二個代表當前節點的特殊指標的值。

樣例輸入:

51 2 3 4 5

3 5 0 2 0

樣例輸出:

1 32 5

3 04 2

5 0

*//*

關鍵:1 pnewnode = createnode();//建立乙個新節點

pnewnode->_ival = pnode->_ival;//注意轉殖,就不需要用到原來的陣列,複製的時候,每次複製,將n'插入在n後面,

pnewnode->_next = pnode->_next;

pnewnode->_sibling = null;

2 if(pnode->_sibling)//如果原來節點n的兄弟節點不為空

node;

node nodearr[maxsize];

int _iindex;

node* createnode()

void buildlist(node** phead,int* parrnext,int* parrsib,int n)//建立時,先按照正常思路來建表

node* pcurnode;

//尾插法建立單鏈表,或者我們可以採用先把節點建立起來,隨後賦值的方法

for(int i = 0 ; i < n - 1; i++)

bool isfirst = true;

for(int i = 1 ; i <= n ; i++)

else

pcurnode->_next = &nodearr[i];

pcurnode = &nodearr[i];

}else//建立頭節點

else

pcurnode = *phead;}}

}void clonelist(node** phead)

node* pnode = *phead;

node* pnewnode;

while(pnode)//

}void connectsibling(node** phead)

node* pnode = *phead,*pclonenode;

while(pnode)

pnode = pclonenode->_next;}}

node* reconnectnode(node** phead)

node* pnode = *phead;

node* pclonehead = null;

node* pclonenode = null;

if(pnode != null)

while(pnode)

return pclonehead;

}void printlist(node* phead)//列印轉殖鍊錶

else

phead = phead->_next;}}

void process()

for(int j = 1 ; j <= n ; j++)

memset(nodearr,null,sizeof(nodearr));

_iindex = 0;

node* head = createnode();

node** phead = &head;

buildlist(phead,iarrnext,iarrsib,n);

clonelist(phead);

connectsibling(phead);

node* pclonehead = reconnectnode(phead);

printlist(pclonehead);}}

int main(int argc,char* argv)

劍指offer 面試題26 複雜鍊錶的複製

以下圖為5個結點的複雜鍊錶,實線表示m pnext指標的指向,虛線表示m psibling指標的指向 解法一 分兩步1 遍歷一遍鍊錶,用m pnext指標將鍊錶連起來,o n 2 假設原始鍊錶中的某節點n的m psibling指向結點s,由於s的位置在鍊錶上有可能在n的前面也可能在n的後面,所以要定...

《劍指Offer》面試題26 複雜鍊錶的複製

劍指offer 面試題26 複雜鍊錶的複製 分解複雜問題 請實現乙個函式用於複製乙個複雜鍊錶。在複雜鍊錶中,每個結點除了有乙個m pnext指標指向下乙個結點外,還有乙個m psibling指向鍊錶中的任意結點或者null。結點的c 定義如下 複雜鍊錶結點定義 struct complexlistn...

(劍指Offer)面試題26 複雜鍊錶的複製

請實現函式complexlistnode clone complexlistnode phead 複製乙個複雜鍊錶。在複雜鍊錶中,每個結點除了有乙個pnext指標指向下乙個結點之外,還有乙個psibling指向鍊錶中的任意結點或者null。結點的定義如下 struct complexlistnode...