題目描述:
輸入乙個鍊錶,輸出該鍊錶中倒數第k個結點。為了符合大多數人的習慣,本題從1開始計數,即鍊錶的尾結點是倒數第1個結點。例如乙個鍊錶有6個結點,從頭結點開始它們的值依次是1,2,3,4,5,6.這個鍊錶的倒數第3個結點是值為4的結點。
思路分析:
為了得到倒數第k個結點,很自然的想法是先走到鍊錶的尾端,再從尾端回溯k步。可是輸入的是單向鍊錶,只有從前往後的指標而沒有從後往前的指標。因此我們需要開啟我們的思路。
既然不能從尾結點開始遍歷這個鍊錶,我們還是把思路回到頭結點上來。假設整個鍊錶有n個結點,那麼倒數第k個結點是從頭結點開始的第n-k-1個結點(從0開始計數)。如果我們能夠得到鍊錶中結點的個數n,那我們只要從頭結點開始往後走n-k-1步就可以了。如何得到結點數n?這個不難,只需要從頭開始遍歷鍊錶,每經過乙個結點,計數器加一就行了。
這種思路的時間複雜度是o(n),但需要遍歷鍊錶兩次。第一次得到鍊錶中結點個數n,第二次得到從頭結點開始的第n--k-1個結點即倒數第k個結點。如 果鍊錶的結點數不多,這是一種很好的方法。但如果輸入的鍊錶的結點個數很多,有可能不能一次性把整個鍊錶都從硬碟讀入物理記憶體,那麼遍歷兩遍意味著乙個結 點需要兩次從硬碟讀入到物理記憶體。我們知道把資料從硬碟讀入到記憶體是非常耗時間的操作。我們能不能把鍊錶遍歷的次數減少到1?
如果可以,將能有效地提高**執行的時間效率。如果我們在遍歷時維持兩個指標,第乙個指標從鍊錶的頭指標開始遍歷,在第k-1步之前,第二個指標保持不動;在第k-1步開始,第二個指標也開始從鍊錶的頭指標開始遍歷。由於兩個指標的距離保持在k-1,當第乙個(走在前面的)指標到達鍊錶的尾結點時,第二個指標(走在後面的)指標正好是倒數第k個結點。這種思路只需要遍歷鍊錶一次。對於很長的鍊錶,只需要把每個結點從硬碟匯入到記憶體一次。因此這一方法的時間效率前面的方法要高。
**實現:
#include
#include
using namespace std;
typedef struct listnode listnode,*node;
int main()
node p=head;
node q=head;
int i=1;
while(p!=null)
else
}cout<<"the data is: "複製**
刪除單鏈表倒數第k個結點
在資料結構這一方面,鍊錶這塊容易搞混的是它的指標。下面的演算法為刪除單鏈表倒數第k個結點,所有的步驟解析都在 裡說明了。刪除單鏈表的倒數第 k個結點.結點定義 classnode public classremotelastedkthnode node node head 遍歷一遍鍊錶,得到 k 最...
查詢單鏈表中的倒數第 k 個結點
思路 1.編寫乙個方法,接收head節點,同時接收乙個index 2.index表示是倒數第index個節點 3.先把鍊錶從頭到尾遍歷,得到鍊錶的總長度getlength 4.得到size後,我們從鍊錶的第乙個開始遍歷 size index個 5.如果找到了返回該節點,否則返回null public...
刪除單鏈表的倒數第k個結點
策略 直接遍歷總數為len,再次遍歷第len k 1個就是答案,但是這樣遍歷了o n k 個,可以在o在更短的時間內找到 圖示 參考 include using namespace std typedef struct listnode listnode void createlist listno...