關于刪除鏈表中的某個結點

鏈表操作是數(shù)據(jù)結構里面最基礎的了,我們都記得數(shù)據(jù)結構書上那個箭頭指來指去的圖暴构,但其實我當時考研的時候也沒有對鏈表從內(nèi)存的角度有一個深刻的認識跪呈,所以我對鏈表操作一直挺頭大的,雖然鏈表只是一種極端的二叉樹丹壕,但我甚至覺得二叉樹比鏈表好操作多了庆械。

眾所周知,鏈表的操作里經(jīng)常要用到fakeHead這么一個頭結點菌赖,作用是一番操作之后缭乘,可以用fakeHead.next用來返回修改后的鏈表。但我有時候疑惑,這個fakeHead會指向改變后的鏈表嗎堕绩。策幼。
比如下面的操作是經(jīng)常會做的:

ListNode fakeHead = new ListNode(-1);
//停留在原點指路
fakeHead.next = head;
//鐵頭娃,去遍歷鏈表
ListNode curNode = fakeHead;

其實仔細想想奴紧,從STACK和HEAP的角度想特姐,保存在HEAP中的fakeHead與curNode(fakeHead對象的引用)都指向了同一塊內(nèi)存,那么鐵頭娃curNode去改變了鏈表(head開頭)的結構之后黍氮,fakeHead只要知道那塊內(nèi)存的起始地址(fakeHead.next)就行了唐含,這個地址有可能改變(比如第一個結點被刪除了)也沒有關系。

下面是我頭腦清醒的狀態(tài)下快速寫出的一個刪除指定value的結點的一個demo沫浆,指針指來指去的那部分最好自己紙上畫畫捷枯,直接看可能比較繞:

/**
 * 刪除node.val 為targetVal的node
 * Created by DrunkPiano on 28/11/2017.
 */

public class DeleteNode {
    private ListNode deleteNode(int targetVal, ListNode head) {
        if (head == null) {
            return null;
        }
        //先用一個fakeHead保存一下head的位置
        ListNode fakeHead = new ListNode(-1);
        fakeHead.next = head;
        ListNode curNode = fakeHead;
        ListNode nextNode = curNode.next;
        while (curNode != null && nextNode != null) {
            if (nextNode.val == targetVal) {
                curNode.next = nextNode.next;
            }
            curNode = curNode.next;
            //判空
            if (curNode != null) {
                nextNode = nextNode.next;
            }
        }
        return fakeHead.next;
    }

    public static void main(String[] args) {
        int[] nodes = {1, 2, 3, 1, 5};
        ListNode fakeHead = new ListNode(-1);
        ListNode head = fakeHead;
        for (Integer i : nodes) {
            head.next = new ListNode(i);
            head = head.next;
        }
        //這里傳入fakeHead.next
        ListNode resNode = new DeleteNode().deleteNode(5, fakeHead.next);
        while (resNode != null) {
            System.out.println(resNode.val + ", ");
            resNode = resNode.next;
        }
    }
}

至于劍指offer之類書上的在O(1)時間刪除節(jié)點,其實是知道targetNode的地址的情況专执。

反轉(zhuǎn)單鏈表

這是個很好的問題淮捆,可以看你對鏈表操作熟悉不熟悉,follow up可以看你對迭代和遞歸是不是熟悉本股。
簡單寫一下迭代和遞歸兩種方法:
Iterative:
類似維護一個prev, cur, next的窗口:

public class MyClass {
    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        ListNode result = new MyClass().reverseList(head);
        while(result != null){
            System.out.println(result.val);
            result = result.next;
        }
    }


    ListNode reverseList(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode prev = null, cur = head, next = null;
        while(cur != null){
            //保存next
            next = cur.next;
            //改變指向
            cur.next = prev;
            //窗口右移
            prev = cur;
            cur = next;
        }
        return prev;
    }
}   
class ListNode{
    ListNode(int value){
        val = value;
    }
    int val;
    ListNode next;
}

recursion:
如果后面還有node攀痊,就遞歸調(diào)用自己來處理后面的node;本質(zhì)上是從倒數(shù)第二個結點開始依次向前改變指向拄显。遞歸的思維難度還是比較難的苟径,尤其是head.next = null;這句不寫的話會產(chǎn)生循環(huán)鏈表導致陷入無限遞歸哦。

public class MyClass {
    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        ListNode result = new MyClass().reverseList(head);
        while(result != null){
            System.out.println(result.val);
            result = result.next;
        }
    }

    ListNode reverseList(ListNode head){
        if(head == null || head.next == null) 
            return head;
        ListNode newHead = reverseList(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }
}
    
class ListNode{
    ListNode(int value){
        val = value;
    }
    int val;
    ListNode next;
}

ref:
http://blog.csdn.net/lavor_zl/article/details/42803431
http://blog.csdn.net/yuxin6866/article/details/52132229
反轉(zhuǎn)單鏈表:
https://www.youtube.com/watch?v=XwIivDg1BlY

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凿叠,一起剝皮案震驚了整個濱河市涩笤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌盒件,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舱禽,死亡現(xiàn)場離奇詭異炒刁,居然都是意外死亡,警方通過查閱死者的電腦和手機誊稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門翔始,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人里伯,你說我怎么就攤上這事城瞎。” “怎么了疾瓮?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵脖镀,是天一觀的道長。 經(jīng)常有香客問我狼电,道長蜒灰,這世上最難降的妖魔是什么弦蹂? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮强窖,結果婚禮上凸椿,老公的妹妹穿的比我還像新娘。我一直安慰自己翅溺,他們只是感情好脑漫,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著咙崎,像睡著了一般窿撬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上叙凡,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天劈伴,我揣著相機與錄音,去河邊找鬼握爷。 笑死跛璧,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的新啼。 我是一名探鬼主播追城,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼燥撞!你這毒婦竟也來了座柱?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤物舒,失蹤者是張志新(化名)和其女友劉穎色洞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冠胯,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡火诸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了荠察。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片置蜀。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖悉盆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情秋秤,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布商架,位于F島的核電站蛇摸,受9級特大地震影響灿巧,放射性物質(zhì)發(fā)生泄漏抠藕。R本人自食惡果不足惜盾似,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一溉跃、第九天 我趴在偏房一處隱蔽的房頂上張望撰茎。 院中可真熱鬧打洼,春花似錦、人聲如沸募疮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽稿蹲。三九已至够掠,卻和暖如春唱捣,著一層夾襖步出監(jiān)牢的瞬間震缭,已是汗流浹背战虏。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留巡社,地道東北人手趣。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓绿渣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怯晕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Java8張圖 11、字符串不變性 12隧出、equals()方法阀捅、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,707評論 0 11
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,139評論 25 707
  • B樹的定義 一棵m階的B樹滿足下列條件: 樹中每個結點至多有m個孩子。 除根結點和葉子結點外忍级,其它每個結點至少有m...
    文檔隨手記閱讀 13,221評論 0 25
  • 大學的時候不好好學習轴咱,老師在講臺上講課烈涮,自己在以為老師看不到的座位看小說窖剑,現(xiàn)在用到了老師講的知識,只能自己看書查資...
    和玨貓閱讀 1,444評論 1 3
  • 讀經(jīng)日期:2017年7月5日 星期三雨 寶貝年齡:8歲6個月 4歲5個月 學經(jīng)人員:瑜琪媽 瑜瑜 琪琪 親子共讀內(nèi)...
    瑜琪媽閱讀 142評論 0 0