1. 程式人生 > 實用技巧 >劍指Offer 36 - 二叉搜尋樹與雙向連結串列

劍指Offer 36 - 二叉搜尋樹與雙向連結串列

力扣連結:https://leetcode-cn.com/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/

題目描述

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。

思路

二叉搜尋樹的中序遍歷結果即是排序的序列,因此我們只需要在中序遍歷的過程中處理每一個被遍歷到的節點的left&right指向,並找到最終要返回的head節點。

pre:當前遍歷到的節點的上一個節點

cur:當前遍歷到的節點

  1. 初始化head = null, pre = head,兩者都為全域性變數。
  2. 中序遍歷二叉樹,對每個節點cur:
    1. 若pre為空,說明是第一個被遍歷到的節點,也就是值最小的節點,儲存為head;
    2. 若pre不為空,將pre和cur連線。
    3. pre = cur
  3. 中序遍歷結束時,pre指向最右節點,將其於頭節點head連線。

程式碼:

/**
 * // Definition for a Node.
 * function Node(val,left,right) {
 *    this.val = val;
 *    this.left = left;
 *    this.right = right;
 * };
 */
/**
 * @param {Node} root
 * @return {Node}
 
*/ var treeToDoublyList = function(root) { if(!root) return null; //中序遍歷,記錄上一個節點pre,每遍歷一個節點調整一次連結串列 let head = null; let pre = head; inorder(root); //中序遍歷後pre指向最右邊的節點,將其與頭節點接上 pre.right = head; head.left = pre; return head; function inorder(cur){
if(!cur) return; inorder(cur.left); //處理當前節點 if(!pre){ head = cur; }else{ pre.right = cur; } cur.left = pre; pre = cur; inorder(cur.right); } };

時間複雜度:O(N)

空間複雜度:O(1)

易錯:

pre一定要設為全域性變數,不能作為引數隨中序遍歷傳遞。如果將pre放在inorder函式中(eg. inorder(cur, pre)),pre = cur 只是將形參pre指向了新的地址,並沒有改變外部pre的值。