题目
二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的
循环双向链表
。对于双向循环链表,第一个节点的前驱是最后一个节点,最后一个节点的后继是第一个节点。
要求不能创建任何新的节点,只能调整树中节点指针的指向。
下图展示了上面的二叉搜索树转化成的链表。“head” 表示指向链表中有最小元素的节点。
思路
我们知道二叉搜索树的特点就是,左
孩子节点的值 < 根
节点的值 < 右
孩子节点的值
所以按照 左根右 的顺序进行遍历,即可实现从小到大的顺序。即树的中序遍历。
法一:递归
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stack>
using namespace std;
struct TreeNode
{
int data;
TreeNode * left;
TreeNode * right;
TreeNode(int value)
{
data = value;
left = NULL;
right = NULL;
}
};
// 借助栈 可以直接在中序遍历的基础上,修改 left 和 right 指针指向的节点
TreeNode * ConvertTreeToList(TreeNode * root)
{
if(root == NULL)
{
return NULL;
}
stack<TreeNode *> s;
s.push(root);
while(root->left)
{
s.push(root->left);
root = root->left;
}
TreeNode * result = new TreeNode(0); // 头结点,不存储数据
TreeNode * temp = result;
while (!s.empty())
{
TreeNode * cur = s.top(); // 当前栈顶元素
TreeNode * curRight = cur->right; // 栈顶元素的右孩子节点
temp->right = cur;
cur->left = temp;
cur->right = NULL;
temp = temp->right;
cout << temp->data << endl;
s.pop();
if(curRight != NULL)
{
s.push(curRight);
while (curRight->left)
{
s.push(curRight->left);
curRight = curRight->left;
}
}
}
result->left = temp;
temp->right = result->right;
return result;
}
int main()
{
TreeNode root(4);
TreeNode node1(2);
TreeNode node2(5);
TreeNode node3(1);
TreeNode node4(3);
root.left = &node1;
root.right = &node2;
node1.left = &node3;
node1.right = &node4;
TreeNode * result = ConvertTreeToList(&root);
for(int i = 0; i < 5 && result != NULL; i++)
{
cout << result->data << " ";
result = result->right;
}
cout << endl;
return 0;
}
法二:借助栈
代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stack>
using namespace std;
struct TreeNode
{
int data;
TreeNode * left;
TreeNode * right;
TreeNode(int value)
{
data = value;
left = NULL;
right = NULL;
}
};
// 递归版本中序遍历
TreeNode * pre = NULL;
TreeNode * head = NULL;
void DFS(TreeNode * node)
{
if(node == NULL)
{
return;
}
// 左
DFS(node->left);
// 根--node
if(pre != NULL)
{
pre->right = node;
}
else
{
head = node;
}
node->left = pre;
pre = node;
// 右
DFS(node->right);
}
TreeNode * DFSConvertTreeToList(TreeNode * root)
{
if(root == NULL)
{
return NULL;
}
// 开始中序递归遍历
DFS(root);
head->left = pre;
pre->right = head;
return head;
}
int main()
{
TreeNode root(4);
TreeNode node1(2);
TreeNode node2(5);
TreeNode node3(1);
TreeNode node4(3);
root.left = &node1;
root.right = &node2;
node1.left = &node3;
node1.right = &node4;
TreeNode *result = DFSConvertTreeToList(&root);
for(int i = 0; i < 5 && result != NULL; i++)
{
cout << result->data << " ";
result = result->right;
}
return 0;
}