線性表可分爲順序表與鏈表,它們是堆棧、隊列、樹、圖等數據結構的實現基礎。數據結構
順序表,線性表的順序存儲結構是指:用一塊地址連續的存儲空間依次存儲線性表中的數據元素。他在邏輯上相鄰的元素在物理上也是相鄰的。什麼意思呢,咱們能夠這樣想象,去食堂排隊打飯,打飯的隊列就是一個順序表,加粗部分的存儲空間指的是咱們排隊所佔據的位置;紅色字體所說的概念能夠理解爲咱們打飯的順序必需要按照從前日後的順序依次進行,即邏輯順序=物理順序,若是此處很差理解,看完下面就好懂了許多。字體
鏈表,相比順序表須要預先佔用一塊事先分配好的存儲空間,鏈表就靈活一些。鏈表中邏輯上相鄰的元素在物理上能夠不相鄰。從這裏能夠看出,鏈表和順序表是在相鄰元素之間存在差別的,這段紅字怎麼理解呢,舉個例子:咱們去銀行辦理業務,銀行都是有取號機的,咱們辦理業務的順序並非順序表那樣的物理順序,而是依據你手上的號碼順序進行辦理,因此呢,咱們就不須要排隊,在辦事大廳隨便坐,當號碼輪到咱們的時候,就能夠辦理了,這就實現了邏輯相鄰但物理順序不相鄰。this
迴歸題目,在鏈表中,鏈表是由N個節點連接而成的線性表,每一個節點由兩部分組成:數據域和指針域。若是其中每一個節點只包含一個指針域那麼就稱爲單鏈表,若是含有兩個指針域那麼就稱爲雙鏈表。結合右上圖來理解:數據域能夠理解成咱們要辦理的業務(好比取多少錢),指針域能夠理解成,取號機裏面取出的號碼。spa
代碼實現定義一個單鏈表以下:3d
public class Node<T> { // 數據域 public T Item { get; set; } // 指針域 public Node<T> Next { get; set; } public Node() { } public Node(T item) { this.Item = item; } }
Node類爲單鏈表的節點,其中包括了一個數據域Item與一個指針域Next(指向後繼節點的位置)。指針
廢話又多了,再次迴歸題目,求鏈表中的倒數第K個節點,直接使用最高效的方法:即爲雙指針法。通俗的理解方法:咱們讓第一個指針先走,當走到第(K-1)個指針時,第二個指針出發,而後同步進行,這樣兩個指針之間的距離一直保持在(k-1),當第一個指針遍歷到最後一點時,那是否是第二個恰好在倒數第K個點呢,不難吧,小學生應該也會。code
class Solution { public ListNode FindKthToTail(ListNode head, int k) { // write code here //魯棒斷定 if(head == null || k == 0) { return null; } //定義先後指針數據與鏈表長度 ListNode a = head; ListNode b = head; int count = 1; //兩指針K差距斷定 while(a!=null) { count++; a = a.next; if((count - k)>1) { b = b.next; } } //鏈表長度不可等於或者小於節點k if (count <= k) { return null; } //返回倒數第K個節點數據 return b; } }
可是,該題目的考點是代碼的魯棒性!!!因此,更要細心的去分析,該題目中存在三處,如下一一解決:blog
1. 空指針問題。解決方案:在代碼中加入了判斷空指針的代碼。隊列
2. 鏈表長度少於k。解決方案:在for循環中增長判斷下一個節點是不是空指針的代碼。get
3. 輸入的參數k爲0。解決方案:在代碼中加入判斷參數k是否爲0的代碼。