http://blog.csdn.net/ljianhui/article/details/22338405
First, the problem description Enter a binary search tree, and now you want to convert the two-fork search tree into a sorted doubly linked list. And in the process of conversion, you cannot create any new nodes, only the point of the node pointer in the tree can be adjusted to implement. Second, realize the idea in the binary search tree, each node has two pointers to its left and right subtree, and the value of the left subtree node is always less than the value of the parent node, and the value of the right subtree node is always greater than the parent node value. In a doubly linked list, each node also has two pointers, which point to the previous node and the latter node, respectively. So the nodes of the two data structures are consistent, the binary search tree is a two-fork search tree, the two-way linked list is doubly linked list, just because two pointers to different points, by changing its pointer to the direction of the implementation is completely possible. For example, the following two-fork search tree, If using the middle sequence traversal, its traversal order is 1-2-3-4-5-6-7, through the appropriate pointer transformation operation, can become the two-way ordered chain list as follows: from, we can see, in order to reduce the number of pointer changes, And to make the operation simpler, when converting to a sort doubly linked list, the pointer to the left Dial hand node is adjusted to the pointer to the previous node in the list, and the pointer to the right child node is adjusted to the pointer to the next node in the list. For example, for a pointer above the value 2, after the adjustment, its previous node is 1, the latter node is 3, and the node 2 of the left Dial hand node is 1, the right child node is originally 3. for the operation of the tree, usually in the process of traversing the various nodes of the tree, through the node implementation of certain operations to complete, This algorithm is no exception. Since the conversion of the two-way linked list is also ordered, and we can see from the above, when we traverse the binary search tree in the middle sequence, its traversal of the node is ordered, so here I take a bit of the traversal order should be the middle order. So how do we adjust the pointer so that the two-fork search tree becomes a two-way ordered list? When traversing to the root node, we can think of the tree as three parts: the root node, the Zoki right subtree of the root. such as the two-fork sorting tree, it is divided into root node 4, the Node 2 is the root of the left dial hand pair and the node 6 is the root of the right subtree. From the list of transformations, we can see that the left pointer of node 4 points to Node 3, the right pointer of node 3 points to Node 4, and because we are using the middle sequence traversal, so when we traverse to the node 4 o'clock, the node 4 of the tree has been transformed into an ordered doubly linked list, The node 3 is the tail node of the converted doubly linked list, so we should use a variable last_node to hold the last node pointer in order to be used when it is contiguous with the root node. The value of this variable last_node is then updated to point to the root node 4. For the right sub-tree of Node 4, take similar action. As for the specific implementation, we only need to recursively place all the subtreesThis can be done. The operation process is as follows: : implementation code
[CPP]View Plaincopyprint?
- #include <iostream>
- #include <stdlib.h>
- #include <time.h>
- Using Std::cout;
- Using Std::cin;
- Using Std::endl;
- struct Bsnode
- {
- //Define the node structure of binary search tree
- Bsnode *left;
- Bsnode *right;
- int data;
- };
- Define various data types to use
- typedef bsnode* Bstree;
- typedef bsnode* Dlist;
- typedef bsnode Dlnode;
- Insert a node with a value of data into a binary search tree
- Bstree Insertnode (bstree tree, int data);
- Turn the two-fork search tree into a doubly linked list and return to the head node.
- Dlist bstreetolist (bstree tree);
- Traverse the binary search tree for each node and adjust the pointer.
- void Convertnode (Bstree tree, Bsnode **last_node);
- Find the leftmost node of a binary search tree
- bsnode* Findleftmostnode (bstree tree);
- Binary search tree with middle order output
- void Printbitree (Bstree tree);
- Output link List
- void Printlist (dlist list);
- Bstree Insertnode (bstree tree, int data)
- {
- if (tree = = NULL)
- {
- //Find insertion point, insert
- Tree = new Bsnode;
- Tree->left = NULL;
- Tree->right = NULL;
- Tree->data = data;
- }
- //Insert in its right subtree
- Else if (Tree->data < data)
- Tree->right = Insertnode (tree->right, data);
- //Insert in its left subtree
- Else if (Tree->data > Data)
- Tree->left = Insertnode (tree->left, data);
- return tree;
- }
- Dlist bstreetolist (Bstree tree)
- {
- if (tree = = NULL)
- return NULL;
- //Find the leftmost node, the head node of the converted list
- Dlnode *head = Findleftmostnode (tree);
- Bsnode *last_node = NULL;
- //To convert
- Convertnode (tree, &last_node);
- return head;
- }
- bsnode* Findleftmostnode (Bstree tree)
- {
- if (tree = = NULL)
- return NULL;
- While (tree->left! = NULL)
- Tree = tree->left;
- return tree;
- }
- void Convertnode (Bstree tree, Bsnode **last_node)
- {
- if (tree = = NULL)
- return;
- //Convert the tree's left subtree, Last_node is the pointer to the last node of the linked list after conversion
- if (tree->left! = NULL)
- Convertnode (Tree->left, Last_node);
- //Adjust the left pointer of the tree to point to the previous node
- Tree->left = *last_node;
- //Adjustment points to the last node, right points to the next node .
- if (*last_node! = NULL)
- (*last_node)->right = tree;
- //Adjust the pointer to a node in the last linked list.
- *last_node = tree;
- //Convert the right subtree of a tree, Last_node is a pointer to the last node of the linked list after conversion
- if (tree->right! = NULL)
- Convertnode (Tree->right, Last_node);
- }
- void Printbstree (Bstree tree)
- {
- if (tree = = NULL)
- return;
- Printbstree (Tree->left);
- cout << tree->data << "";
- Printbstree (Tree->right);
- }
- void Printlist (dlist list)
- {
- Dlnode *node = list;
- While (node! = NULL)
- {
- cout << node->data << "";
- node = node->right;
- }
- }
- int main ()
- {
- Bstree tree = NULL;
- Srand (Time (NULL));
- cout << "Insert Data Order is:" << Endl;
- For (int i = 0; i <; ++i)
- {
- //Insert random 10 numbers to generate a two-fork sort tree
- int data = rand ()%100;
- cout << data << "";
- Tree = Insertnode (tree, data);
- }
- cout << "\nthe bstree is:" << Endl;
- Printbstree (tree);
- //To convert
- Tree = bstreetolist (tree);
- cout << "\nbitree to List:" << Endl;
- Printlist (tree);
- return 0;
- }
The results are as follows: Four, code analysis because the binary sorting tree is not allowed to have the same elements, in the randomly generated 10 number, there are two of the same 3 and 73, so actually inserted into the two fork sorting tree node only 8, and then we are in the middle order to traverse the output binary sorting tree data, Then output the converted linked list of data, found that the order is consistent, thus proving the correctness of the algorithm. The core functions of the algorithm are Bstreetolist,convertnode and Findleftmostnode. As we can see in the function bstreetolist, we have a variable last_node used to record the converted list of the end nodes, because in the convention we return the 1th node of the list (counting from 1), and Last_node points to the last node, We can take the pointer from the end of the tail to get the first node pointer, but here I do not, because it needs to traverse each node once, the time complexity of O (n). Instead, a pointer to the leftmost node of the two-fork sort tree is found before the transformation. Because the sort binary tree is ordered, the leftmost node is the smallest node, and our algorithm does not delete or add nodes, that is, the address of the node is not changed, so the leftmost node is the 1th node of the converted list, its time complexity is O (logn). Five, time complexity and space complexity the algorithm starts from the root point to the left, finds the leftmost node, has a time complexity of O (Logn), and then iterates through each node in the two-fork sort tree for pointer transformation, with a time complexity of O (n), so the total time complexity is O (n). As for the spatial complexity, because the Convertnode function makes recursive calls, its function has two open parameters, and the function call layer in the function stack does not exceed the height of the tree, so its space complexity is O (logn).
Binary search tree converted to ordered doubly linked list