logo

バイナリ ツリーを循環二重リンク リストに変換する

GfG Practice で試してみる リストするツリー' title= #practiceLinkDiv { 表示: なし !重要; }

与えられた 二分木 それをに変換します 循環二重リンクリスト (その場で)。  

  • ノード内の左ポインタと右ポインタは、変換された循環リンク リスト内でそれぞれ前ポインタと次ポインタとして使用されます。
  • List 内のノードの順序は、指定されたバイナリ ツリーの Inorder と同じである必要があります。
  • Inorder traversal の最初のノードは、循環リストのヘッド ノードである必要があります。

例:



' title=

推奨される実践方法 バイナリツリーからCDLLへ 試してみてください!

再帰を使用してバイナリ ツリーを循環二重リンク リストに変換します。

このアイデアは、指定された 2 つの循環二重リストを連結する汎用関数を作成することです。

問題を解決するには、次の手順に従ってください。



  • 左側のサブツリーを循環 DLL に再帰的に変換します。変換されたリストを次のようにします 左リスト
  • 右側のサブツリーを循環 DLL に再帰的に変換します。変換されたリストを次のようにします 右リスト 。 
  • ツリーのルートの循環リンク リストを作成し、左右のルートが自分自身を指すようにします。 
  • 連結する 左リスト 単一のルートノードのリストを使用します。 
  • 上記の手順で作成したリストを次のように連結します。 右リスト

注記: 上記のアプローチは、Postorder 方式でツリーを横断します。順番通りに横断することもできます。最初に左側のサブツリーとルートを連結し、次に右側のサブツリーを再帰して、その結果を左側のルート連結と連結します。

2 つの循環 DLL を連結するにはどうすればよいですか?  

  • 左側のリストの最後のノードを取得します。ヘッドの prev ポインタがリストの最後のノードを指しているため、最後のノードの取得は O(1) 操作です。
  • それを右側のリストの最初のノードに接続します
  • 2 番目のリストの最後のノードを取得します
  • リストの先頭に接続します。

以下は上記のアイデアの実装です。



C++
// C++ Program to convert a Binary Tree // to a Circular Doubly Linked List #include    using namespace std; // To represents a node of a Binary Tree struct Node {  struct Node *left *right;  int data; }; // A function that appends rightList at the end // of leftList. Node* concatenate(Node* leftList Node* rightList) {  // If either of the list is empty  // then return the other list  if (leftList == NULL)  return rightList;  if (rightList == NULL)  return leftList;  // Store the last Node of left List  Node* leftLast = leftList->left;  // Store the last Node of right List  Node* rightLast = rightList->left;  // Connect the last node of Left List  // with the first Node of the right List  leftLast->right = rightList;  rightList->left = leftLast;  // Left of first node points to  // the last node in the list  leftList->left = rightLast;  // Right of last node refers to the first  // node of the List  rightLast->right = leftList;  return leftList; } // Function converts a tree to a circular Linked List // and then returns the head of the Linked List Node* bTreeToCList(Node* root) {  if (root == NULL)  return NULL;  // Recursively convert left and right subtrees  Node* left = bTreeToCList(root->left);  Node* right = bTreeToCList(root->right);  // Make a circular linked list of single node  // (or root). To do so make the right and  // left pointers of this node point to itself  root->left = root->right = root;  // Step 1 (concatenate the left list with the list  // with single node i.e. current node)  // Step 2 (concatenate the returned list with the  // right List)  return concatenate(concatenate(left root) right); } // Display Circular Link List void displayCList(Node* head) {  cout << 'Circular Linked List is :n';  Node* itr = head;  do {  cout << itr->data << ' ';  itr = itr->right;  } while (head != itr);  cout << 'n'; } // Create a new Node and return its address Node* newNode(int data) {  Node* temp = new Node();  temp->data = data;  temp->left = temp->right = NULL;  return temp; } // Driver Program to test above function int main() {  Node* root = newNode(10);  root->left = newNode(12);  root->right = newNode(15);  root->left->left = newNode(25);  root->left->right = newNode(30);  root->right->left = newNode(36);  Node* head = bTreeToCList(root);  displayCList(head);  return 0; } // This code is contributed by Aditya Kumar (adityakumar129) 
C
// C Program to convert a Binary Tree // to a Circular Doubly Linked List #include  #include  // To represents a node of a Binary Tree typedef struct Node {  struct Node *left *right;  int data; } Node; // A function that appends rightList at the end // of leftList. Node* concatenate(Node* leftList Node* rightList) {  // If either of the list is empty  // then return the other list  if (leftList == NULL)  return rightList;  if (rightList == NULL)  return leftList;  // Store the last Node of left List  Node* leftLast = leftList->left;  // Store the last Node of right List  Node* rightLast = rightList->left;  // Connect the last node of Left List  // with the first Node of the right List  leftLast->right = rightList;  rightList->left = leftLast;  // Left of first node points to  // the last node in the list  leftList->left = rightLast;  // Right of last node refers to the first  // node of the List  rightLast->right = leftList;  return leftList; } // Function converts a tree to a circular Linked List // and then returns the head of the Linked List Node* bTreeToCList(Node* root) {  if (root == NULL)  return NULL;  // Recursively convert left and right subtrees  Node* left = bTreeToCList(root->left);  Node* right = bTreeToCList(root->right);  // Make a circular linked list of single node  // (or root). To do so make the right and  // left pointers of this node point to itself  root->left = root->right = root;  // Step 1 (concatenate the left list with the list  // with single node i.e. current node)  // Step 2 (concatenate the returned list with the  // right List)  return concatenate(concatenate(left root) right); } // Display Circular Link List void displayCList(Node* head) {  printf('Circular Linked List is :n');  Node* itr = head;  do {  printf('%d ' itr->data);  itr = itr->right;  } while (head != itr);  printf('n'); } // Create a new Node and return its address Node* newNode(int data) {  Node* temp = (Node*)malloc(sizeof(Node));  temp->data = data;  temp->left = temp->right = NULL;  return temp; } // Driver Program to test above function int main() {  Node* root = newNode(10);  root->left = newNode(12);  root->right = newNode(15);  root->left->left = newNode(25);  root->left->right = newNode(30);  root->right->left = newNode(36);  Node* head = bTreeToCList(root);  displayCList(head);  return 0; } // This code is contributed by Aditya Kumar (adityakumar129) 
Java
// Java Program to convert a Binary Tree to a // Circular Doubly Linked List // Node class represents a Node of a Tree class Node {  int val;  Node left right;  public Node(int val)  {  this.val = val;  left = right = null;  } } // A class to represent a tree class Tree {  Node root;  public Tree() { root = null; }  // concatenate both the lists and returns the head  // of the List  public Node concatenate(Node leftList Node rightList)  {  // If either of the list is empty then  // return the other list  if (leftList == null)  return rightList;  if (rightList == null)  return leftList;  // Store the last Node of left List  Node leftLast = leftList.left;  // Store the last Node of right List  Node rightLast = rightList.left;  // Connect the last node of Left List  // with the first Node of the right List  leftLast.right = rightList;  rightList.left = leftLast;  // left of first node refers to  // the last node in the list  leftList.left = rightLast;  // Right of last node refers to the first  // node of the List  rightLast.right = leftList;  // Return the Head of the List  return leftList;  }  // Method converts a tree to a circular  // Link List and then returns the head  // of the Link List  public Node bTreeToCList(Node root)  {  if (root == null)  return null;  // Recursively convert left and right subtrees  Node left = bTreeToCList(root.left);  Node right = bTreeToCList(root.right);  // Make a circular linked list of single node  // (or root). To do so make the right and  // left pointers of this node point to itself  root.left = root.right = root;  // Step 1 (concatenate the left list with the list  // with single node i.e. current node)  // Step 2 (concatenate the returned list with the  // right List)  return concatenate(concatenate(left root) right);  }  // Display Circular Link List  public void display(Node head)  {  System.out.println('Circular Linked List is :');  Node itr = head;  do {  System.out.print(itr.val + ' ');  itr = itr.right;  } while (itr != head);  System.out.println();  } } // Driver Code class Main {  public static void main(String args[])  {  // Build the tree  Tree tree = new Tree();  tree.root = new Node(10);  tree.root.left = new Node(12);  tree.root.right = new Node(15);  tree.root.left.left = new Node(25);  tree.root.left.right = new Node(30);  tree.root.right.left = new Node(36);  // head refers to the head of the Link List  Node head = tree.bTreeToCList(tree.root);  // Display the Circular LinkedList  tree.display(head);  } } 
Python3
# Python3 Program to convert a Binary # Tree to a Circular Doubly Linked List class newNode: def __init__(self data): self.data = data self.left = self.right = None # A function that appends rightList # at the end of leftList. def concatenate(leftList rightList): # If either of the list is empty # then return the other list if (leftList == None): return rightList if (rightList == None): return leftList # Store the last Node of left List leftLast = leftList.left # Store the last Node of right List rightLast = rightList.left # Connect the last node of Left List # with the first Node of the right List leftLast.right = rightList rightList.left = leftLast # Left of first node points to # the last node in the list leftList.left = rightLast # Right of last node refers to # the first node of the List rightLast.right = leftList return leftList # Function converts a tree to a circular # Linked List and then returns the head # of the Linked List def bTreeToCList(root): if (root == None): return None # Recursively convert left and # right subtrees left = bTreeToCList(root.left) right = bTreeToCList(root.right) # Make a circular linked list of single # node (or root). To do so make the # right and left pointers of this node # point to itself root.left = root.right = root # Step 1 (concatenate the left list # with the list with single # node i.e. current node) # Step 2 (concatenate the returned list # with the right List) return concatenate(concatenate(left root) right) # Display Circular Link List def displayCList(head): print('Circular Linked List is :') itr = head first = 1 while (head != itr or first): print(itr.data end=' ') itr = itr.right first = 0 print() # Driver Code if __name__ == '__main__': root = newNode(10) root.left = newNode(12) root.right = newNode(15) root.left.left = newNode(25) root.left.right = newNode(30) root.right.left = newNode(36) head = bTreeToCList(root) displayCList(head) # This code is contributed by PranchalK 
C#
// C# Program to convert a Binary Tree // to a Circular Doubly Linked List using System; // Node class represents a Node of a Tree public class Node {  public int val;  public Node left right;  public Node(int val)  {  this.val = val;  left = right = null;  } } // A class to represent a tree public class Tree {  internal Node root;  public Tree() { root = null; }  // concatenate both the lists  // and returns the head of the List  public virtual Node concatenate(Node leftList  Node rightList)  {  // If either of the list is empty  // then return the other list  if (leftList == null) {  return rightList;  }  if (rightList == null) {  return leftList;  }  // Store the last Node of left List  Node leftLast = leftList.left;  // Store the last Node of right List  Node rightLast = rightList.left;  // Connect the last node of Left List  // with the first Node of the right List  leftLast.right = rightList;  rightList.left = leftLast;  // left of first node refers to  // the last node in the list  leftList.left = rightLast;  // Right of last node refers to  // the first node of the List  rightLast.right = leftList;  // Return the Head of the List  return leftList;  }  // Method converts a tree to a circular  // Link List and then returns the head  // of the Link List  public virtual Node bTreeToCList(Node root)  {  if (root == null) {  return null;  }  // Recursively convert left  // and right subtrees  Node left = bTreeToCList(root.left);  Node right = bTreeToCList(root.right);  // Make a circular linked list of single  // node (or root). To do so make the  // right and left pointers of this node  // point to itself  root.left = root.right = root;  // Step 1 (concatenate the left list with  // the list with single node  // i.e. current node)  // Step 2 (concatenate the returned list  // with the right List)  return concatenate(concatenate(left root) right);  }  // Display Circular Link List  public virtual void display(Node head)  {  Console.WriteLine('Circular Linked List is :');  Node itr = head;  do {  Console.Write(itr.val + ' ');  itr = itr.right;  } while (itr != head);  Console.WriteLine();  } } // Driver Code public class GFG {  public static void Main(string[] args)  {  // Build the tree  Tree tree = new Tree();  tree.root = new Node(10);  tree.root.left = new Node(12);  tree.root.right = new Node(15);  tree.root.left.left = new Node(25);  tree.root.left.right = new Node(30);  tree.root.right.left = new Node(36);  // head refers to the head of the Link List  Node head = tree.bTreeToCList(tree.root);  // Display the Circular LinkedList  tree.display(head);  } } // This code is contributed by Shrikant13 
JavaScript
<script> // javascript Program to convert a Binary Tree to a // Circular Doubly Linked List // Node class represents a Node of a Tree class Node {  constructor(val) {  this.val = val;  this.left = null;  this.right = null;  } } // A class to represent a   var root = null;  // concatenate both the lists and returns the head  // of the List  function concatenate(leftList rightList) {  // If either of the list is empty then  // return the other list  if (leftList == null)  return rightList;  if (rightList == null)  return leftList;  // Store the last Node of left List  var leftLast = leftList.left;  // Store the last Node of right List  var rightLast = rightList.left;  // Connect the last node of Left List  // with the first Node of the right List  leftLast.right = rightList;  rightList.left = leftLast;  // left of first node refers to  // the last node in the list  leftList.left = rightLast;  // Right of last node refers to the first  // node of the List  rightLast.right = leftList;  // Return the Head of the List  return leftList;  }  // Method converts a to a circular  // Link List and then returns the head  // of the Link List  function bTreeToCList(root) {  if (root == null)  return null;  // Recursively convert left and right subtrees  var left = bTreeToCList(root.left);  var right = bTreeToCList(root.right);  // Make a circular linked list of single node  // (or root). To do so make the right and  // left pointers of this node point to itself  root.left = root.right = root;  // Step 1 (concatenate the left list with the list  // with single node i.e. current node)  // Step 2 (concatenate the returned list with the  // right List)  return concatenate(concatenate(left root) right);  }  // Display Circular Link List  function display(head) {  document.write('Circular Linked List is :  
'
); var itr = head; do { document.write(itr.val + ' '); itr = itr.right; } while (itr != head); document.write(); } // Driver Code // Build the root = new Node(10); root.left = new Node(12); root.right = new Node(15); root.left.left = new Node(25); root.left.right = new Node(30); root.right.left = new Node(36); // head refers to the head of the Link List var head = bTreeToCList(root); // Display the Circular LinkedList display(head); // This code contributed by umadevi9616 </script>

出力
Circular Linked List is : 25 12 30 10 36 15 

時間計算量: の上) すべてのノードが最大 1 回アクセスされるためです。
補助スペース: O(log N) 余分なスペースは再帰呼び出しスタックで使用され、バイナリ ツリーであるため最大サイズ logN まで増加する可能性があります。

インオーダートラバーサルによるバイナリツリーから循環二重リンクリストへの変換:

このアイデアは、バイナリ ツリーを順番に走査することです。順序トラバーサルを実行している間、以前に訪問したノードを変数で追跡します。 前へ 。訪問したノードごとに、次のノードにします。 前へ このノードの前を次のように設定します 前へ

問題を解決するには、次の手順に従ってください。

  • まずバイナリツリーを二重リンクリストに変換します。この投稿を参照してください 指定されたバイナリ ツリーを二重リンク リストに変換する 。
  • 次に、最初と最後のノードを接続して、この二重リンク リストを循環二重リンク リストに変換します。

以下は、上記のアプローチの実装です。

C++
// A C++ program for in-place conversion of Binary Tree to // CDLL #include    using namespace std; /* A binary tree node has - data  left and right pointers  */ struct Node {  int data;  Node* left;  Node* right; }; // A utility function that converts given binary tree to // a doubly linked list // root --> the root of the binary tree // head --> head of the created doubly linked list Node* BTree2DoublyLinkedList(Node* root Node** head) {  // Base case  if (root == NULL)  return root;  // Initialize previously visited node as NULL. This is  // static so that the same value is accessible in all  // recursive calls  static Node* prev = NULL;  // Recursively convert left subtree  BTree2DoublyLinkedList(root->left head);  // Now convert this node  if (prev == NULL)  *head = root;  else {  root->left = prev;  prev->right = root;  }  prev = root;  // Finally convert right subtree  BTree2DoublyLinkedList(root->right head);  return prev; } // A simple recursive function to convert a given Binary // tree to Circular Doubly Linked List using a utility // function root --> Root of Binary Tree tail --> Pointer to // tail node of created circular doubly linked list Node* BTree2CircularDoublyLinkedList(Node* root) {  Node* head = NULL;  Node* tail = BTree2DoublyLinkedList(root &head);  // make the changes to convert a DLL to CDLL  tail->right = head;  head->left = tail;  // return the head of the created CDLL  return head; } /* Helper function that allocates a new node with the given data and NULL left and right pointers. */ Node* newNode(int data) {  Node* new_node = new Node;  new_node->data = data;  new_node->left = new_node->right = NULL;  return (new_node); } /* Function to print nodes in a given circular doubly linked  * list */ void printList(Node* head) {  if (head == NULL)  return;  Node* ptr = head;  do {  cout << ptr->data << ' ';  ptr = ptr->right;  } while (ptr != head); } /* Driver program to test above functions*/ int main() {  // Let us create the tree shown in above diagram  Node* root = newNode(10);  root->left = newNode(12);  root->right = newNode(15);  root->left->left = newNode(25);  root->left->right = newNode(30);  root->right->left = newNode(36);  // Convert to DLL  Node* head = BTree2CircularDoublyLinkedList(root);  // Print the converted list  printList(head);  return 0; } // This code was contributed by Abhijeet // Kumar(abhijeet19403) 
Java
// A Java program for in-place conversion of Binary Tree to // CDLL // A binary tree node has - data left pointer and right // pointer class Node {  int data;  Node left right;  public Node(int data)  {  this.data = data;  left = right = null;  } } class BinaryTree {  Node root;  // head --> Pointer to head node of created doubly  // linked list  Node head;  // Initialize previously visited node as NULL. This is  // static so that the same value is accessible in all  // recursive calls  static Node prev = null;  // A simple utility recursive function to convert a  // given Binary tree to Doubly Linked List root --> Root  // of Binary Tree  void BTree2DoublyLinkedList(Node root)  {  // Base case  if (root == null)  return;  // Recursively convert left subtree  BTree2DoublyLinkedList(root.left);  // Now convert this node  if (prev == null)  head = root;  else {  root.left = prev;  prev.right = root;  }  prev = root;  // Finally convert right subtree  BTree2DoublyLinkedList(root.right);  }  // A simple function to convert a given binary tree to  // Circular doubly linked list  // using a utility function  void BTree2CircularDoublyLinkedList(Node root)  {  BTree2DoublyLinkedList(root);  // make the changes to convert a DLL to CDLL  prev.right = head;  head.left = prev;  }  /* Function to print nodes in a given doubly linked list  */  void printList(Node node)  {  if (node == null)  return;  Node curr = node;  do {  System.out.print(curr.data + ' ');  curr = curr.right;  } while (curr != node);  }  // Driver program to test above functions  public static void main(String[] args)  {  // Let us create the tree as shown in above diagram  BinaryTree tree = new BinaryTree();  tree.root = new Node(10);  tree.root.left = new Node(12);  tree.root.right = new Node(15);  tree.root.left.left = new Node(25);  tree.root.left.right = new Node(30);  tree.root.right.left = new Node(36);  // convert to DLL  tree.BTree2CircularDoublyLinkedList(tree.root);  // Print the converted List  tree.printList(tree.head);  } } // This code has been contributed by Abhijeet // Kumar(abhijeet19403) 
Python
# A python program for in-place conversion of Binary Tree to DLL # A binary tree node has data left pointers and right pointers class Node: def __init__(self val): self.data = val self.left = None self.right = None # head --> Pointer to head node of created doubly linked list head = None # Initialize previously visited node as NULL. This is # so that the same value is accessible in all recursive # calls prev = None # A simple recursive function to convert a given Binary tree # to Doubly Linked List # root --> Root of Binary Tree def BinaryTree2DoubleLinkedList(root): # Base case if (root == None): return # Recursively convert left subtree BinaryTree2DoubleLinkedList(root.left) # Now convert this node global prev head if (prev == None): head = root else: root.left = prev prev.right = root prev = root # Finally convert right subtree BinaryTree2DoubleLinkedList(root.right) # Function to print nodes in a given doubly linked list def printList(node): while (node != None): print(node.data) node = node.right # Driver program to test above functions # Let us create the tree as shown in above diagram root = Node(10) root.left = Node(12) root.right = Node(15) root.left.left = Node(25) root.left.right = Node(30) root.right.left = Node(36) # convert to DLL BinaryTree2DoubleLinkedList(root) # Print the converted List printList(head) # This code is contributed by adityamaharshi21. 
C#
// A C# program for in-place conversion of Binary Tree to // CDLL using System; public class Node {  public int data;  public Node left right;  public Node(int data)  {  this.data = data;  left = right = null;  } } public class BinaryTree {  Node root;  // head --> Pointer to head node of created doubly  // linked list  Node head;  // Initialize previously visited node as NULL. This is  // static so that the same value is accessible in all  // recursive calls  static Node prev = null;  // A simple utility recursive function to convert a  // given Binary tree to Doubly Linked List root --> Root  // of Binary Tree  void BTree2DoublyLinkedList(Node root)  {  // Base case  if (root == null)  return;  // Recursively convert left subtree  BTree2DoublyLinkedList(root.left);  // Now convert this node  if (prev == null)  head = root;  else {  root.left = prev;  prev.right = root;  }  prev = root;  // Finally convert right subtree  BTree2DoublyLinkedList(root.right);  }  // A simple function to convert a given binary tree to  // Circular doubly linked list  // using a utility function  void BTree2CircularDoublyLinkedList(Node root)  {  BTree2DoublyLinkedList(root);  // make the changes to convert a DLL to CDLL  prev.right = head;  head.left = prev;  }  /* Function to print nodes in a given doubly linked list  */  void printList(Node node)  {  if (node == null)  return;  Node curr = node;  do {  Console.Write(curr.data + ' ');  curr = curr.right;  } while (curr != node);  }  static public void Main()  {  // Let us create the tree as shown in above diagram  BinaryTree tree = new BinaryTree();  tree.root = new Node(10);  tree.root.left = new Node(12);  tree.root.right = new Node(15);  tree.root.left.left = new Node(25);  tree.root.left.right = new Node(30);  tree.root.right.left = new Node(36);  // convert to DLL  tree.BTree2CircularDoublyLinkedList(tree.root);  // Print the converted List  tree.printList(tree.head);  } } // This code is contributed by lokesh(lokeshmvs21). 
JavaScript
// A javascript program for in-place conversion of Binary Tree to DLL // A binary tree node has data left pointers and right pointers class Node {  constructor(val) {  this.data = val;  this.left = null;  this.right = null;  } } var root; // head --> Pointer to head node of created doubly linked list var head; // Initialize previously visited node as NULL. This is // so that the same value is accessible in all recursive // calls var prev = null; // A simple recursive function to convert a given Binary tree // to Doubly Linked List // root --> Root of Binary Tree function BinaryTree2DoubleLinkedList(root) {  // Base case  if (root == null)  return;    // Recursively convert left subtree  BinaryTree2DoubleLinkedList(root.left);    // Now convert this node  if (prev == null)  head = root;  else {  root.left = prev;  prev.right = root;  }  prev = root;    // Finally convert right subtree  BinaryTree2DoubleLinkedList(root.right); } /* Function to print nodes in a given doubly linked list */ function printList(node) {  while (node != null) {  console.log(node.data + ' ');  node = node.right;  } } // Driver program to test above functions // Let us create the tree as shown in above diagram root = new Node(10); root.left = new Node(12); root.right = new Node(15); root.left.left = new Node(25); root.left.right = new Node(30); root.right.left = new Node(36); // convert to DLL BinaryTree2DoubleLinkedList(root); // Print the converted List printList(head); // This code is contributed by ishankhandelwals. 

出力
25 12 30 10 36 15 

時間計算量: O(N) すべてのノードが最大 1 回アクセスされるため。
補助スペース: O(log N) 余分なスペースは再帰的な関数呼び出しスタックで使用され、最大サイズ logN まで増加する可能性があります。

このアプローチは次の寄稿者によって提供されました。 アビジート・クマール