私は自分で解決策を見つけたと思います: 以下は完全な Java 実装です ロジック + 擬似コードは以下のとおりです [1] ツリーの左端のノードを見つけ、それが LinkList の先頭になり、クラスに保存します
Node HeadOfList = null;
findTheHeadOfInorderList (Node root)
{
Node curr = root;
while(curr.left != null)
curr = curr.left;
HeadOfList = curr; // Curr will hold the head of the list
}
[2] ツリーを逆順に走査して、ツリーを右ポインタの LL に変換し、左ポインタが常にノードの親を指していることを確認します。
updateInorderSuccessor(Node root, Node inorderNext, Node parent)
{
if(root != null)
//Recursively call with the right child
updateInorderSuccessor(root.right, inorderNext, root);
// Update the in-order successor in right pointer
root.right = inorderNext;
inorderNext = root;
//Recursively call with the left child
updateInorderSuccessor(root.left, inorderNext, root);
// Update the parent in left pointer
root.left = parent;
}
}
[3] 元に戻すには:
リストをトラバースし、左ポインタが null のノードを見つけます。それをルートにし、リンクリスト内のこのルートのリンクを解除し、その子からも解除します...
これでリンク リストは左サブツリー用と右サブツリー用の 2 つの部分に分割されます. これら 2 つのリストのルートを再帰的に見つけて, 左右の子にします. 関数 restoreBST() を参照してください.
Node restoreBST(Node head)
{
if(head == null || (head.left == null && head.right == null)) return root;
Node prev, root, right, curr;
curr = head;
// Traverse the list and find the node with left as null
while(curr != null)
{
if(curr.left == null)
{
// Found the root of this tree
root = curr;
// Save the head of the right list
right = curr.right;
// Detach the children of the root just found, these will be updated later as a part of the recursive solution
detachChildren(curr, head);
break;
}
prev = curr;
curr = curr.right;
}
// By now the root is found and the children of the root are detached from it.
// Now disconnect the right pointer based connection in the list for the root node, so that list is broken in to two list, one for left subtree and one for right subtree
prev.right = null;
root.right = null;
// Recursively call for left and right subtree
root.left = restoreBST(head);
root.right = restoreBST(right);
//now root points to its proper children, lets return the root
return root;
}
子をデタッチするロジックは単純です。リストを繰り返し処理し、左ポインタがルートに等しいノードを探します。
private void detachChildren(AvlNode root, AvlNode head) {
AvlNode curr = head;
while(curr != null)
{
if(curr.left == root)
{
curr.left = null;
}
curr = curr.right;
}
}