二叉樹的每個結點有兩個指針,在不創建新結點的情況下,更改結點指針的指向可將二叉樹轉換為鏈表結構,二叉樹中的左右結點變為鏈表中的左右結點。使用兩個每個結點的兩個指針可轉換為雙鏈表結構,只使用每個結點的右指針可轉換為單鏈表結構。
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
}
};