原文地址: http://blog.csdn.net/wcyoot/article/details/6428297
题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。
比如将二元查找树
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
很明显我们可以知道 中序遍历 一遍二叉查找树就可以得到一个递增的序列。同样,只要中序遍历一下儿茶查找数,调整一下左孩子指针和右孩子指针的指向,就可以得到一个双向链表。
代码中的pListHead和pListLast的初始值都是NULL,其中pListHead只需要赋值一次,也就是向左走到头的时候,代码中就是pListHead和pListLast都是NULL的时候,这时候,将pListHead指向当前节点就好了,在之后的遍历中,pListLast访问当前遍历的节点的时候是指向之前的节点的,所以需要pListLast->pRChild = pTreeRoot,之后,再将pListLast指向当前遍历的节点。代码如下:
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); }