最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

面試題:用 Java 逆序打印鏈表

 更新時間:2018年07月04日 10:29:56   作者:nanchen2251  
這篇文章主要介紹了面試題:用 Java 逆序打印鏈表,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

昨天的 Java 實現(xiàn)單例模式 中,我們的雙重檢驗鎖機制因為指令重排序問題而引入了 volatile 關(guān)鍵字,不少朋友問我,到底為啥要加 volatile 這個關(guān)鍵字呀,而它,到底又有什么神奇的作用呢?

volatile 這個關(guān)鍵字,在昨天的講解中我們簡單說了一下:被 volatile 修飾的共享變量,都會具有下面兩個屬性:

  • 保證不同線程對該變量操作的內(nèi)存可見性。
  • 禁止指令重排序。

共享變量:如果一個變量在多個線程的工作內(nèi)存中都存在副本,那么這個變量就是這幾個線程的共享變量。

可見性:一個線程對共享變量值的修改,能夠及時地被其它線程看到。

對于重排序,不熟悉的建議直接 Google 一下,這里也就不多提了。只需要記住,在多線程中操作一個共享變量的時候,一定要記住加上 volatile 修飾即可。

由于時間關(guān)系,我們還是得先進入今天的正題,對于 volatile 關(guān)鍵字,在要求并發(fā)編程能力的面試中還是很容易考察到的,后面我也會簡單給大家講解。

輸入一個單鏈表的頭結(jié)點,從尾到頭打印出每個結(jié)點的值。

我們的鏈表有很多,單鏈表,雙向鏈表,環(huán)鏈表等。這里是最普通的單鏈表模式,我們一般會在數(shù)據(jù)存儲區(qū)域存放數(shù)據(jù),然后有一個指針指向下一個結(jié)點。雖然 Java 中沒有指針這個概念,但 Java 的引用恰如其分的填補了這個問題。

看到這道題,我們往往會很快反應到每個結(jié)點都有 next 屬性,所以要從頭到尾輸出很簡單。于是我們自然而然就會想到先用一個 while 循環(huán)取出所有的結(jié)點存放到數(shù)組中,然后再通過逆序遍歷這個數(shù)組,即可實現(xiàn)逆序打印單鏈表的結(jié)點值。

我們假定結(jié)點的數(shù)據(jù)為 int 型的。實現(xiàn)代碼如下:

public class Test05 {
  public static class Node {
    int data;
    Node next;
  }

  public static void printLinkReverse(Node head) {
    ArrayList<Node> nodes = new ArrayList<>();
    while (head != null) {
      nodes.add(head);
      head = head.next;
    }
    for (int i = nodes.size() - 1; i >= 0; i--) {
      System.out.print(nodes.get(i).data + " ");
    }
  }

  public static void main(String[] args) {
    Node head = new Node();
    head.data = 1;
    head.next = new Node();
    head.next.data = 2;
    head.next.next = new Node();
    head.next.next.data = 3;
    head.next.next.next = new Node();
    head.next.next.next.data = 4;
    head.next.next.next.next = new Node();
    head.next.next.next.next.data = 5;
    printLinkReverse(head);
  }
}

這樣的方式確實能實現(xiàn)逆序打印鏈表的數(shù)據(jù),但明顯用了整整兩次循環(huán),時間復雜度為 O(n²)。等等!逆序輸出?似乎有這樣一個數(shù)據(jù)結(jié)構(gòu)可以完美解決這個問題,這個數(shù)據(jù)結(jié)構(gòu)就是棧。

棧是一種「后進先出」的數(shù)據(jù)結(jié)構(gòu),用棧的原理更好能達到我們的要求,于是實現(xiàn)代碼如下:

public class Test05 {
  public static class Node {
    int data;
    Node next;
  }

  public static void printLinkReverse(Node head) {
    Stack<Node> stack = new Stack<>();
    while (head != null) {
      stack.push(head);
      head = head.next;
    }
    while (!stack.isEmpty()) {
      System.out.print(stack.pop().data + " ");
    }
  }

  public static void main(String[] args) {
    Node head = new Node();
    head.data = 1;
    head.next = new Node();
    head.next.data = 2;
    head.next.next = new Node();
    head.next.next.data = 3;
    head.next.next.next = new Node();
    head.next.next.next.data = 4;
    head.next.next.next.next = new Node();
    head.next.next.next.next.data = 5;
    printLinkReverse(head);
  }
}

既然可以用棧來實現(xiàn),我們也極容易想到遞歸也能解決這個問題,因為遞歸本質(zhì)上也就是一個棧結(jié)構(gòu)。要實現(xiàn)逆序輸出鏈表,我們每訪問一個結(jié)點的時候,我們先遞歸輸出它后面的結(jié)點,再輸出該結(jié)點本身,這樣鏈表的輸出結(jié)果自然也是反過來了。

代碼如下:

public class Test05 {
  public static class Node {
    int data;
    Node next;
  }

  public static void printLinkReverse(Node head) {
    if (head != null) {
      printLinkReverse(head.next);
      System.out.print(head.data+" ");
    }
  }

  public static void main(String[] args) {
    Node head = new Node();
    head.data = 1;
    head.next = new Node();
    head.next.data = 2;
    head.next.next = new Node();
    head.next.next.data = 3;
    head.next.next.next = new Node();
    head.next.next.next.data = 4;
    head.next.next.next.next = new Node();
    head.next.next.next.next.data = 5;
    printLinkReverse(head);
  }
}

雖然遞歸代碼看起來確實很整潔,但有個問題:當鏈表非常長的時候,一定會導致函數(shù)調(diào)用的層級很深,從而有可能導致函數(shù)調(diào)用棧溢出。所以顯示用?;谘h(huán)實現(xiàn)的代碼,健壯性還是要好一些的。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實現(xiàn)圖片倒影的源碼實例內(nèi)容

    Java實現(xiàn)圖片倒影的源碼實例內(nèi)容

    在本篇文章里小編給大家整理的是關(guān)于Java實現(xiàn)圖片倒影的源碼以及相關(guān)知識點,有需要的朋友們學習下。
    2019-09-09
  • 解決maven加載依賴時遇到的問題

    解決maven加載依賴時遇到的問題

    這篇文章主要介紹了解決maven加載依賴時遇到的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • SpringBoot應用監(jiān)控Actuator使用隱患及解決方案

    SpringBoot應用監(jiān)控Actuator使用隱患及解決方案

    SpringBoot的Actuator 模塊提供了生產(chǎn)級別的功能,比如健康檢查,審計,指標收集,HTTP 跟蹤等,幫助我們監(jiān)控和管理Spring Boot 應用,本文將給大家介紹SpringBoot應用監(jiān)控Actuator使用隱患及解決方案,需要的朋友可以參考下
    2024-07-07
  • MyBatis查詢?、修改?、刪除操作示例代碼

    MyBatis查詢?、修改?、刪除操作示例代碼

    MyBatis?作為一款靈活的持久層框架,提供了直接編寫?SQL?語句的能力,避免了其他?ORM?框架可能帶來的性能和功能限制,本文介紹?MyBatis?中如何高效執(zhí)行這三種操作,并通過代碼示例展示最佳實踐,感興趣的朋友一起看看吧
    2024-08-08
  • Java中&&與?表達式結(jié)合時出現(xiàn)的坑

    Java中&&與?表達式結(jié)合時出現(xiàn)的坑

    這篇文章主要給大家介紹了關(guān)于Java中&&與?表達式結(jié)合時出現(xiàn)的坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-02-02
  • springsecurity基于token的認證方式

    springsecurity基于token的認證方式

    本文主要介紹了springsecurity基于token的認證方式,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 深入理解Java8新特性之Lambda表達式的基本語法和自定義函數(shù)式接口

    深入理解Java8新特性之Lambda表達式的基本語法和自定義函數(shù)式接口

    Lambda 表達式,也可稱為閉包,它是推動 Java 8 發(fā)布的最重要新特性。Lambda 允許把函數(shù)作為一個方法的參數(shù)(函數(shù)作為參數(shù)傳遞進方法中)。使用 Lambda 表達式可以使代碼變的更加簡潔緊湊
    2021-11-11
  • Spring MVC框架配置方法詳解

    Spring MVC框架配置方法詳解

    這篇文章主要為大家詳細介紹了Spring MVC框架的配置方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • Java將數(shù)組轉(zhuǎn)換成字符串的四種方法總結(jié)

    Java將數(shù)組轉(zhuǎn)換成字符串的四種方法總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java將數(shù)組轉(zhuǎn)換成字符串的四種方法,每種方法都有其適用的場景和優(yōu)缺點,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-12-12
  • springboot的logback配置源碼解讀

    springboot的logback配置源碼解讀

    這篇文章主要為大家介紹了springboot的logback配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-11-11

最新評論

云霄县| 隆子县| 岫岩| 竹北市| 临洮县| 泗洪县| 德令哈市| 青阳县| 治县。| 米脂县| 涿州市| 开平市| 安塞县| 武安市| 庆安县| 苗栗县| 潼关县| 科尔| 托克逊县| 仁怀市| 萨迦县| 定陶县| 梧州市| 永丰县| 乐安县| 汽车| 板桥市| 光山县| 进贤县| 平阴县| 瓮安县| 德钦县| 兴文县| 合山市| 衡阳市| 宜阳县| 顺平县| 水富县| 江陵县| 磐安县| 溆浦县|