一、題目描述
1.1 題目
-
變異版二叉搜索樹與雙向鏈表
-
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的循環雙向鏈表。要求不能創建任何新的節點,只能調整樹中節點指針的指向。
-
爲了讓您更好地理解問題,以下面的二叉搜索樹爲例:
-
我們希望將這個二叉搜索樹轉化爲雙向循環鏈表。鏈表中的每個節點都有一個前驅和後繼指針。對於雙向循環鏈表,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。
-
下圖展示了上面的二叉搜索樹轉化成的鏈表。“head” 表示指向鏈表中有最小元素的節點。
- 特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指針需要指向前驅,樹中節點的右指針需要指向後繼。還需要返回鏈表中的第一個節點的指針。
1.2 知識點
- 二叉樹
- 雙向循環鏈表
二、解題思路
2.1 解題思路
跟《劍指Offer》尋找 二叉搜索樹與雙向鏈表 的思路相似,只不過在該題中需要形成的是 雙向循環鏈表 ,因此需要保存尾結點。對於頭結點就是第一個遍歷到的值(直接判斷 Head 是否爲 Null 然後賦值即可),而尾結點應當是最後一個遍歷到的值(需要在遍歷的過程中不斷更新賦值)。
三、實現代碼
3.1 代碼實現
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val,Node _left,Node _right) {
val = _val;
left = _left;
right = _right;
}
};
*/
class Solution {
private Node pre;
private Node head;
private Node rear;
public Node treeToDoublyList(Node root) {
if(root == null) return null;
traceback(root);
head.left = rear;
rear.right = head;
return head;
}
public void traceback(Node root) {
if(root == null) return;
traceback(root.left);
root.left = pre;
if(pre != null) pre.right = root;
pre = root;
if(head == null) head = pre;
traceback(root.right);
rear = pre;
}
}