二叉树的每个结点有两个指针,在不创建新结点的情况下,更改结点指针的指向可将二叉树转换为链表结构,二叉树中的左右结点变为链表中的左右结点。使用两个每个结点的两个指针可转换为双链表结构,只使用每个结点的右指针可转换为单链表结构。
1、若要把二叉搜索树转换为排序的双向链表,只需中序遍历树中的每个结点,遍历的过程中始终保存已生成链表的最右端结点,当遍历父亲结点的时候将父亲结点加入到左子树生成的链表的最右端结点的后面,接着再遍历父亲结点的右子树,整个遍历完成后的最右端结点即是链表的最右端结点。
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
TreeNode *pLastNodeInList = NULL;
Convert(pRootOfTree, &pLastNodeInList);
while(pLastNodeInList && pLastNodeInList->left)
pLastNodeInList = pLastNodeInList->left;
return pLastNodeInList;
}
void Convert(TreeNode *pNode, TreeNode **pLastNodeInList) {
if(!pNode)
return;
if(pNode->left)
Convert(pNode->left, pLastNodeInList);
pNode->left = *pLastNodeInList;
if(*pLastNodeInList) //可能为NULL
(*pLastNodeInList)->right = pNode;
*pLastNodeInList = pNode;
if(pNode->right)
Convert(pNode->right, pLastNodeInList);
}
};
2、若要把一般二叉树转换为单链表结构,只需后序遍历每个结点,在遍历父亲结点的时候将左子树形成的链表插入到父亲结点和右子树形成的链表中间。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
void flatten(TreeNode* root) {
if(!root) return;
flatten(root->left);
flatten(root->right);
if(!root->left) return;
TreeNode *pNode = root->left; //将左子树生成的链表插入到root与root->right中间
while(!pNode->right) //得到左子树生成的链表的最右端结点
pNode = pNode->right;
pNode->right = root->right;
root->right = root->left;
root->left = NULL; //NULL root root->left pNode->right root->right
}
};