Question
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
关键词:链表 二叉搜索树 中序遍历
Solution
中序遍历
由于搜索树节点大小为左<根<右,因此用中序遍历(左根右)二叉树得到排序号的链表,更新链表的left、right。
时间复杂度:O(N)
空间复杂度:O(N)
- Python
class Solution:
def Convert(self, pRootOfTree):
if not pRootOfTree:
return None
lian = []
def getList(node):
if not node:
return
getList(node.left)
lian.append(node)
getList(node.right)
getList(pRootOfTree)
for i in range(len(lian)):
if i > 0:
lian[i].left = lian[i-1]
if i < len(lian)-1:
lian[i].right = lian[i+1]
return lian[0]
- C++
class Solution {
vector<TreeNode*> lian;
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree)
return NULL;
getList(pRootOfTree);
for(int i=0; i<lian.size(); i++){
if(i > 0)
lian[i]->left = lian[i-1];
if(i < lian.size()-1)
lian[i]->right = lian[i+1];
}
return lian[0];
}
void getList(TreeNode* p){
if(!p)
return;
getList(p->left);
lian.push_back(p);
getList(p->right);
}
};
递归
将问题拆分成:将左子树拆成有序链表(递归),右子树拆成有序链表(递归),当前根节点left指向左子树,right指向右子树。
时间复杂度:O(N)
空间复杂度:O(1)
- Python
class Solution:
# 返回二叉树转链表的表头
def Convert(self, pRootOfTree):
if not pRootOfTree:
return None
# 得到左子树转链表的表头
left_h = self.Convert(pRootOfTree.left)
# 得到右子树转链表的表头
right_h = self.Convert(pRootOfTree.right)
temp = left_h
if temp:
while temp.right:
temp = temp.right
# 左子树链表的表尾才是当前节点的左边
temp.right = pRootOfTree
pRootOfTree.left = temp
# 右子树链表的表头就是当前节点的右边
pRootOfTree.right = right_h
if right_h:
right_h.left = pRootOfTree
#注意如果左子树不存在,则表头为当前节点,若当前节点不存在,在函数第一个判断中已经返回None
return left_h if left_h else pRootOfTree
- C++
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree)
{
if(!pRootOfTree)
return NULL;
TreeNode* left_h = Convert(pRootOfTree->left);
TreeNode* right_h = Convert(pRootOfTree->right);
TreeNode* temp = left_h;
if(temp){
while(temp->right)
temp = temp->right;
temp->right = pRootOfTree;
pRootOfTree->left = temp;
}
pRootOfTree->right = right_h;
if(right_h)
right_h->left = pRootOfTree;
return left_h? left_h:pRootOfTree;
}
};