二元查找树转变成排序的双向链表
把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该转换成个排 序的双向链表。
要求不能创建任何新的结点,只调整指针向。
10
/ \
6 14
/ \ / \
4 8 12 8
转换成双向链表
4=6=8=10=12=14=16
利用中序遍历来解决比较简单,这里我主要提供一种非递归版本来解决这个问题
递归版本:(copy自http://blog.csdn.net/wcyoot/article/details/6428297)
template<typename T> struct TreeNode { T data; TreeNode* pLChild; TreeNode* pRChild; }; // 要求两个输出参数要初始化为NULL template<typename T> void ConvertBSTree2List(TreeNode<T>* pTreeRoot/*树的根节点*/, TreeNode<T>*& pListHead/*双向链表的头指针*/, TreeNode<T>*& pListLast/*双向链表的尾指针*/) { if (pTreeRoot == NULL) { return; } // 中序遍历左子树 ConvertBSTree2List(pTreeRoot->pLChild, pListHead, pListLast); // 处理当前节点,把节点链到双向链表尾部 // 修改当前节点左指针,指向双向链表尾部 pTreeRoot->pLChild = pListLast; if (pListLast) // 非第一个节点 { pListLast->pRChild = pTreeRoot; } else // 第一个节点 { pListHead = pTreeRoot; } pListLast = pTreeRoot; // 中序遍历右子树 ConvertBSTree2List(pTreeRoot->pRChild, pListHead, pListLast); }
非递归版本:(如果对iteration遍历二叉树方法不清楚,可以参考二叉树的前序、中序、后序遍历非递归实现)
TreeNode* turnTreeToDLinkList(TreeNode *root) { TreeNode *head = root; if (head == nullptr) return head; stack<TreeNode*> sta; sta.push(root); TreeNode* lastRoot = root; TreeNode *preNode = nullptr; while (!sta.empty()) { root = sta.top(); if (lastRoot != root->right) { if (lastRoot != root->left) { if (root->left != nullptr) { sta.push(root->left); continue; } } root->left = preNode; if (preNode) preNode->right = root; else head = root; preNode = root; if (root->right != nullptr) { sta.push(root->right); continue; } } lastRoot = root; sta.pop(); } return head; }