Address: http://zhedahht.blog.163.com/blog/static/254111742007127104759245/
Question: enter a binary search tree and convert it into a sorted two-way linked list. You must not create any new node. You only need to adjust the pointer point.
For example, Binary Search Tree
10
/\
6 14
/\/\
4 8 12 16
Convert to a two-way linked list
4 = 6 = 8 = 10 = 12 = 14 = 16.
Analysis: This is Microsoft's interview question. Many tree-related questions are solved by recursive thinking, and this question is no exception. Next we will use two different recursive ideas for analysis.
Idea 1: when we arrive at a certain node and want to adjust the subtree whose root node is used as the node, first adjust its left subtree to convert the left subtree into a sorted left sublinked list, then adjust its right subtree to convert the right sublinked list. The rightmost node of the left sub-linked list (the maximum node of the left sub-tree), the current node, and the leftmost node of the right sub-linked list (the smallest node of the right sub-tree ). Recursively adjust all nodes from the root node of the tree.
Thought 2: We can traverse the entire tree in a central order. Traverse the tree in this way, and access a small node first. If we access each node and assume that the previously accessed node has been adjusted to a sorted two-way linked list, we will then link the pointer of the current node to the end of the linked list. When all nodes are accessed, the entire tree is converted into a sorted two-way linked list.
Reference code:
First, we define the data structure of the Binary Search Tree node as follows:
struct BSTreeNode // a node in the binary search tree { int m_nValue; // value of node BSTreeNode *m_pLeft; // left child of node BSTreeNode *m_pRight; // right child of node };
Code corresponding to the idea:
///////////////////////////////////////////////////////////////////////// Covert a sub binary-search-tree into a sorted double-linked list// Input: pNode - the head of the sub tree// asRight - whether pNode is the right child of its parent// Output: if asRight is true, return the least node in the sub-tree// else return the greatest node in the sub-tree///////////////////////////////////////////////////////////////////////BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight){ if(!pNode) return NULL; BSTreeNode *pLeft = NULL; BSTreeNode *pRight = NULL; // Convert the left sub-tree if(pNode->m_pLeft) pLeft = ConvertNode(pNode->m_pLeft, false); // Connect the greatest node in the left sub-tree to the current node if(pLeft) { pLeft->m_pRight = pNode; pNode->m_pLeft = pLeft; } // Convert the right sub-tree if(pNode->m_pRight) pRight = ConvertNode(pNode->m_pRight, true); // Connect the least node in the right sub-tree to the current node if(pRight) { pNode->m_pRight = pRight; pRight->m_pLeft = pNode; } BSTreeNode *pTemp = pNode; // If the current node is the right child of its parent, // return the least node in the tree whose root is the current node if(asRight) { while(pTemp->m_pLeft) pTemp = pTemp->m_pLeft; } // If the current node is the left child of its parent, // return the greatest node in the tree whose root is the current node else { while(pTemp->m_pRight) pTemp = pTemp->m_pRight; } return pTemp;}///////////////////////////////////////////////////////////////////////// Covert a binary search tree into a sorted double-linked list// Input: the head of tree// Output: the head of sorted double-linked list///////////////////////////////////////////////////////////////////////BSTreeNode* Convert(BSTreeNode* pHeadOfTree){ // As we want to return the head of the sorted double-linked list, // we set the second parameter to be true return ConvertNode(pHeadOfTree, true);}
Code corresponding to idea 2:
///////////////////////////////////////////////////////////////////////// Covert a sub binary-search-tree into a sorted double-linked list// Input: pNode - the head of the sub tree// pLastNodeInList - the tail of the double-linked list///////////////////////////////////////////////////////////////////////void ConvertNode(BSTreeNode* pNode, BSTreeNode*& pLastNodeInList){ if(pNode == NULL) return; BSTreeNode *pCurrent = pNode; // Convert the left sub-tree if (pCurrent->m_pLeft != NULL) ConvertNode(pCurrent->m_pLeft, pLastNodeInList); // Put the current node into the double-linked list pCurrent->m_pLeft = pLastNodeInList; if(pLastNodeInList != NULL) pLastNodeInList->m_pRight = pCurrent; pLastNodeInList = pCurrent; // Convert the right sub-tree if (pCurrent->m_pRight != NULL) ConvertNode(pCurrent->m_pRight, pLastNodeInList);}///////////////////////////////////////////////////////////////////////// Covert a binary search tree into a sorted double-linked list// Input: pHeadOfTree - the head of tree// Output: the head of sorted double-linked list///////////////////////////////////////////////////////////////////////BSTreeNode* Convert_Solution1(BSTreeNode* pHeadOfTree){ BSTreeNode *pLastNodeInList = NULL; ConvertNode(pHeadOfTree, pLastNodeInList); // Get the head of the double-linked list BSTreeNode *pHeadOfList = pLastNodeInList; while(pHeadOfList && pHeadOfList->m_pLeft) pHeadOfList = pHeadOfList->m_pLeft; return pHeadOfList;}
The non-recursive algorithm is as follows. Some stack operations must be completed by yourself:
BiTree Link(BiTree T){BiTree p;int i=0;InitStack();while(T != NULL || !StackEmpty(S)){while(T != NULL){Push(S,T);T = T->lchild;}if(!StackEmpty(S)){T = Pop(S);if(i == 0){i++;p = T;p->lchild = NULL;printf("%c",T->value); }else{p->rchild = T;T->lchild = p;p = p->rchild;printf("%c",T->value);}T = T->rchild;}}printf("\n");p->rchild = NULL;return p;}