题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
参考文献:剑指offer 何海涛老师 P152
思路:将该二叉搜索树转换成一个排序的双向链表,这整个转变过程,抓住排序的二叉搜索树特征,可以类似二叉树的中序遍历。只不过中序遍历中间处理过程只是输出下根节点。而这里中间处理过程变成了将二叉搜索树转换成双向链表。
#include "myHead.h"
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
TreeNode* Convert(TreeNode* pRootOfTree)
{
TreeNode* doubleLinkedList = NULL;// *doubleLinkedList指向二叉树的最右孩子
ConvertTree2List(pRootOfTree,&doubleLinkedList);
while(doubleLinkedList!=NULL && doubleLinkedList->left!=NULL){//必须加上doubleLinkedList!=NULL判断。否则当二叉树为null,循环越界。
doubleLinkedList = doubleLinkedList->left;
}
return doubleLinkedList;
}
void ConvertTree2List(TreeNode* root,TreeNode** tail){
TreeNode *pCur;
pCur = root;
if(pCur == NULL)
return ;
//处理左子树
if(pCur->left!=NULL){
ConvertTree2List(pCur->left,tail);
}
//当遍历到节点的最左子树,递归结束,开始处理。
//因为上面的一步走到最左子树叶子节点pCur,它为非空,它的左孩子为空。故开始构造双向链表。
//每次构造,都是将一个工作指针pCur指向的节点的左孩子指向上一次遍历得到的循环链表尾节点tail。tail的右孩子指针这个pCur
//分两种情况。第一种,这个节点是根的最左孩子。那么它应该是整棵树的最小数,即只有指向右边指针无左指针。
//此时构造双向链表很简单,只有这个叶子节点pCur.即pCur->left = null.然后将循环链表尾节点设为当前的工作指针pCur
//第二种 ,这个节点表示根的最左孩子。即它是某个节点右孩子的最左孩子。那么它的左孩子应该是循环链表的尾节点。
// 上一次遍历得到的循环链表尾节点*tail->right=pCUr。pCur-> left = *tail;然后将循环链表尾节点设为当前的工作指针pCur
if(*tail!= NULL){
(*tail)->right = pCur;
}
pCur->left = *tail;
*tail = pCur;
//处理右子树
if(pCur->right !=NULL){
ConvertTree2List(pCur->right,tail);
}
}