演算法之遞迴(3) 鍊錶操作

2022-08-11 16:21:16 字數 2960 閱讀 5659

演算法之遞迴(3)- 鍊錶操作

遞迴(2)嘗試了乙個單鏈表的遍歷,同時又分析了如何新增自己的操作,是在遞迴呼叫之前,還是在遞迴呼叫之後。

今天,打算將問題深入一下,即新增相應的操作在遞迴的過程中。

解法一

逐層遞迴,遍歷到最後乙個節點,並從返回的節點一次向後遞迴,遍歷n次,找到倒數第n個節點。

private lnode targetnode = null

;

private lnode findlastnthnode(lnode head, int

index)

findlastnthnode(head.next, index);

lnode tmpnode =head;

while ((head.next != null) && (index > 0

))

if (head.next == null && index == 0

)

return

targetnode;

}

分析

1. 額外的全域性性的輔助變數。

2. 時間複雜度為o(index * n),n為鍊錶的長度。

3. 效能開銷較大。

解法二(解法一的變形)

每當遍歷到當前節點,即再迴圈向後遍歷n個,如果節點遍歷到最後,並且index自減等於0,說明當前節點即為要找的倒數第n個。也就是說解法一是從後向前找,而解法二是從前向後找。

private lnode targetnode2 = null

;

private lnode findlastnthnode2(lnode head, int

index)

if (head == null && index == 0

)

return

targetnode2;

}

分析:與解法一一樣。

解法三

定義乙個全域性變數,用來計數,當遞迴從最後乙個節點返回時,計數器減減,當等於0時,這個節點即是要找的倒數第n個節點。

private

int counter = 0

;

private

lnode targetnode2;

private lnode findlastnthnode2(lnode head, int

index)

findlastnthnode2(head.next, index);

counter--;

if (counter == 0

)

return

targetnode2;

}

分析

1. 兩個輔助變數。

2. 時間複雜度為o(n)。

3. 多餘的index,累贅的counter。

其實以上幾個解決方案個人覺得都不夠perfect。

像類似於鍊錶這樣的操作,基本就是兩指標。

於是我重新給了乙個方案如下。

(該段**已經編譯、執行及測試通過)

解法四:

using

system;

using

system.collections.generic;

using

system.linq;

using

system.text;

namespace

; node lucas = new

node()

;node bill = new

node()

;node steve = new

node()

;node anders = new

node()

;node jordan = new

node()

;head.next =lucas;

lucas.next =bill;

bill.next =steve;

steve.next =anders;

anders.next =jordan;

program p = new

program();

node resultnode = p.findlastnthnode(head, 2

); console.writeline(resultnode.data);

console.readline();

}private node findlastnthnode(node node, int

n)

if(n <= 0

)

node node1 =node;

node node2 =node;

return

this

.internalfindlastnthnode(node1, node2, n);

}private node internalfindlastnthnode(node node1, node node2, int

n)

if(n == 0

)

return

this.internalfindlastnthnode(node1.next, node2, --n);}}

public

class

node

public node next

}}

best regards,

lucas luo

原創 演算法之遞迴(3) 鍊錶操作

演算法之遞迴 3 鍊錶操作 遞迴 2 嘗試了乙個單鏈表的遍歷,同時又分析了如何新增自己的操作,是在遞迴呼叫之前,還是在遞迴呼叫之後。今天,打算將問題深入一下,即新增相應的操作在遞迴的過程中。解法一 逐層遞迴,遍歷到最後乙個節點,並從返回的節點一次向後遞迴,遍歷n次,找到倒數第n個節點。private...

演算法篇之鍊錶操作

主要是積累演算法篇關於鍊錶操作,我們都知道鍊錶有單向鍊錶,雙向鍊錶,環形鍊錶等各種形式。但是這部落格主要是積累相關鍊錶操作。如下說到的listnode定義如下 typedef struct node listnode 常用兩種方法 就地反轉法 在於不通過申請新的鍊錶,基於原鍊錶實現就地反轉,需要多申...

鍊錶演算法之鍊錶分化

對於乙個鍊錶,我們需要用乙個特定閾值完成對它的分化,使得小於等於這個值的結點移到前面,大於該值的結點在後面,同時保證兩類結點內部的位置關係不變。給定乙個鍊錶的頭結點head,同時給定閾值val,請返回乙個鍊錶,使小於等於它的結點在前,大於等於它的在後,保證結點值不重複。測試樣例 3 思路 新建兩個鍊...