title: 2019-8-23 二叉搜索树与双向链表
tags: 算法,每日一题,二叉树,链表
二叉搜索树与双向链表
1. 题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
2.题目解析
二叉搜索树的中序遍历就是一个排好顺序的序列,所以关键是对二叉搜索树的中序遍历前后的节点进行重新连接。这里连接的方式为节点的right指向下一个节点,left指向上一个节点。
2.1 思路解析
这里有两种方式来对中序遍历进行重新连接。
方案一:使用一个vector保存遍历的结果,然后将vector中的元素前后相连组成一个双向链表。
方案二:只在在进行中序遍历时就进行重新连接,主要就是要记录当前节点之前的节点是哪一个。
/*
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)
{
if(pRootOfTree == NULL || (pRootOfTree->left == NULL && pRootOfTree->right == NULL)) return pRootOfTree;
return Convert2(pRootOfTree);
}
//right指向下一个节点,left指向上一个节点
TreeNode* Convert1(TreeNode* pRootOfTree){//方法一:使用一个vector保存二叉搜索树的中序遍历结果
stack<TreeNode*> help_stack;
TreeNode* head = pRootOfTree;
vector<TreeNode*> res;
while( head != NULL || !help_stack.empty()){
if(head != NULL){
help_stack.push(head);
head = head->left;
}else{
head = help_stack.top(); help_stack.pop();
res.push_back(head);
head = head->right;
}
}
res[0]->left = NULL;
for(int i=0; i<res.size()-1; ++i){
res[i]->right = res[i+1];
res[i+1]->left = res[i];
}
res[res.size()-1]->left = res[res.size()-2];
res[res.size()-1]->right = NULL;
return res[0];
}
TreeNode* Convert2(TreeNode* pRootOfTree){//方法二:使用记录的方式
stack<TreeNode*> help_stack;
TreeNode* new_head = NULL;
TreeNode* head = pRootOfTree;
TreeNode* pre = NULL;
while(head != NULL || !help_stack.empty()){
if(head != NULL){
help_stack.push(head);
head = head->left;
}else{
head = help_stack.top(); help_stack.pop();
if(new_head == NULL) new_head = head;//新的链表的头
//构建双链表
head->left = pre;
if(pre) pre->right = head;
pre = head;
head = head->right;
}
}
return new_head;
}
};
更多关于编程和机器学习资料请关注FlyAI公众号。