这是一道面试题,将 二叉搜索树 -> 排序双向链表, 虽然是一道面试题, 不过也给我们提供了一种思路, 二叉搜索树和双向链表这两种我们常用的数据结构, 他们之间可以进行互相转换吗? 倒也是一个值得玩味的想法。
思路:根据 二叉搜索树 的性质,要转换为 有序双向链表, 则, 中序遍历最适合。 因为中序遍历出来是有序的,由小到大。
二叉搜索树每个节点有两个指针分别指向左右两个孩子, 双向链表每个结点有两个指针分别指向前一个结点和后一个结点。如图:
我们需要将如左图的二叉搜索树 转换为 右下角的 有序双向链表。
我们给出实现代码:
//将二叉搜索树->排序双向链表,不能创建任何新节点,只能调整树中结点指针的指向.
//思路:根据 二叉搜索树 的性质,要转换为 有序双向链表, 则, 中序遍历最适合。 因为中序遍历出来是有序的,由小到大。
//二叉搜索树每个节点有两个指针分别指向左右两个孩子, 双向链表每个结点有两个指针分别指向前一个结点和后一个结点, 如图。
#include <iostream>
#include <windows.h>
using namespace std;
//定义二叉搜索树结点结构
struct BSTNode
{
BSTNode* _left;
BSTNode* _right;
int _data;
BSTNode( int data, BSTNode* left = NULL, BSTNode* right = NULL )
: _data( data )
, _left( left )
, _right( right )
{}
};
//插入新结点到树中
void Insert( BSTNode*& tree, int data );
//将二叉搜索树tree转化成双向链表,并返回头结点
BSTNode* BSTreeToList( BSTNode* tree );
//遍历二叉搜索树tree的各个结点,并进行指针调整
void ConvertNode( BSTNode* tree, BSTNode*& lastNodeInList );
//查找二叉搜索树tree的最左结点
BSTNode* FindLeftmostNode( BSTNode* tree );
//以中序遍历打印二叉搜索树tree
void PrintBiTree( BSTNode* tree );
//打印链表
void PrintList( BSTNode* headOfList );
void Insert( BSTNode*& tree, int data )
{
if ( NULL == tree )
{
tree = new BSTNode( data, NULL, NULL );
}
else if ( data < tree->_data )
{
Insert( tree->_left, data );
}
else if ( data > tree->_data )
{
Insert( tree->_right, data );
}
else
{
return;
}
}
BSTNode* BSTreeToList( BSTNode* tree )
{
if ( NULL == tree )
{
return NULL;
}
//找到最左边的结点,即转换后链表的头结点
BSTNode* headOfList = FindLeftmostNode( tree );
BSTNode* lastNodeInList = NULL;
//进行转换
ConvertNode( tree, lastNodeInList );
return headOfList;
}
BSTNode* FindLeftmostNode( BSTNode* tree )
{
if ( NULL == tree )
{
return NULL;
}
while ( NULL != tree->_left )
{
tree = tree->_left;
}
return tree;
}
void ConvertNode( BSTNode* tree, BSTNode*& lastNodeInList )
{
if ( NULL == tree )
{
return;
}
//对tree的左子树进行转换,lastNodeInList是转换后链表中最后一个结点的指针
if ( NULL != tree->_left )
{
ConvertNode( tree->_left, lastNodeInList );
}
//调整tree的left指针,指向上一个结点
tree->_left = lastNodeInList;
//调整最后一个结点指针的指向,使它的 right 指向下一个结点(即此时的结点tree)
if ( NULL != lastNodeInList )
{
lastNodeInList->_right = tree;
}
//调整指向最后链表一个结点的指针
lastNodeInList = tree;
//对tree的右子树进行转换,lastNodeInList是转换后链表最后一个结点的指针
if ( NULL != tree->_right )
{
ConvertNode( tree->_right, lastNodeInList );
}
}
void PrintBSTree( BSTNode* tree )
{
if ( NULL == tree )
{
return;
}
PrintBSTree( tree->_left );
cout << tree->_data << " ";
PrintBSTree( tree->_right );
}
void PrintList( BSTNode* headOfList )
{
if ( NULL == headOfList )
{
return;
}
BSTNode* node = headOfList;
while ( NULL != node )
{
cout << node->_data << " ";
node = node->_right;
}
cout << endl;
}
int main()
{
BSTNode* tree = NULL;
int a[] = { 626, 1226, 521, 100, 600, 80, 110 };
for ( size_t i = 0; i < (sizeof(a) / sizeof( a[0] )); ++i )
{
Insert( tree, a[i] );
}
PrintBSTree(tree);
cout << endl;
//进行转换
BSTNode* headOfList = BSTreeToList( tree );
PrintList( headOfList );
system( "pause" );
return 0;
}