微软算法面试(1):把二元查找树转变成排序的双向链表(树)
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ /
6 14
/ / / /
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
实现如下:
#include<iostream>
using namespace std;
//定义二元查找树
struct BSTreeNode
{
int m_nValue;
BSTreeNode *left;
BSTreeNode *right;
BSTreeNode(int _value = 0):m_nValue(_value),left(NULL),right(NULL){}
void add(BSTreeNode* _node)
{
if(_node->m_nValue > m_nValue)
{
if(right != NULL)
right->add(_node);
else
right = _node;
}
else
{
if(left != NULL)
left->add(_node);
else
left = _node;
}
}
};
//查找二元查找树的最右节点
BSTreeNode* findrightNode(BSTreeNode* BT)
{
if(BT == NULL)
return NULL;
BSTreeNode* rBT = BT;
while(rBT->right != NULL)
rBT = rBT->right;
return rBT;
}
//查找二元查找树的最左节点
BSTreeNode* findleftNode(BSTreeNode* BT)
{
if(BT == NULL)
return NULL;
BSTreeNode* rBT = BT;
while(rBT->left != NULL)
rBT = rBT->left;
return rBT;
}
//把二元查找树转成有序的双向链表
void BST_Blist(BSTreeNode* root)
{
if(root == NULL)
return;
BSTreeNode* left = findrightNode(root->left);
BSTreeNode* right = findleftNode(root->right);
BST_Blist(root->left);
BST_Blist(root->right);
if(left == root)
left = NULL;
if(right == root)
right = NULL;
root->left = left;
if(left != NULL)
left->right = root;
root->right = right;
if(right != NULL)
right->left = root;
}
template <typename T, int size=1024>
class queue{
private:
T data[size];
int begin, end;
public:
queue():begin(0),end(0){}
bool empty()
{
return begin == end;
}
void push(T& _d)
{
if((end +1)%size == begin)
{
cout << "queue is full, cann't push any node." <<endl;
return;
}
data[end] = _d;
end = (end + 1)%size;
}
T& pop(T& _t)
{
if(end == begin)
{
cout << "queue is empty, cann't pop any node." <<endl;
return _t;
}
_t = data[begin];
begin = (begin + 1)%size;
return _t;
}
};
void print(BSTreeNode* root)
{
queue<BSTreeNode*> q;
BSTreeNode* node = root;
BSTreeNode _n1(-1);//空标记
q.push(node);
while(!q.empty())
{
BSTreeNode* _bsn = &_n1;
q.pop(_bsn);
cout << _bsn->m_nValue << " ";
if(_bsn->left != NULL)
q.push(_bsn->left);
if(_bsn->right != NULL)
q.push(_bsn->right);
}
}
int main()
{
//构建二元查找树
cout << "构建二元查找树 为:" << endl;
cout << " 8" << endl;
cout << " / /" << endl;
cout << " 6 10" << endl;
cout << "/ / / /" << endl;
cout << "5 7 9 11" << endl;
BSTreeNode *root = NULL;
BSTreeNode node1(10);
BSTreeNode node2(6);
BSTreeNode node3(14);
BSTreeNode node4(4);
BSTreeNode node5(8);
BSTreeNode node6(12);
BSTreeNode node7(16);
root = &node1;
root->add(&node2);
root->add(&node3);
root->add(&node4);
root->add(&node5);
root->add(&node6);
root->add(&node7);
//打印二叉查找树
cout << "按层从左到右,打印二叉查找树" <<endl;
print(root);
//转化成排序的双向链表(树)
BST_Blist(root);
BSTreeNode *next = findleftNode(root);
cout << endl << "转化成排序的双向链表 结果为:" << endl;
while(next != NULL)
{
if(next->right != NULL)
cout << next->m_nValue << "==";
else
cout << next->m_nValue;
next = next->right;
}
}
把代码存储为文件main.cpp
在linux环境下编译为:
g++ main.cpp -o main
运行:./main
输出结果为:
构建二元查找树 为:
8
/ /
6 10
/ / / /
5 7 9 11
按层从左到右,打印二叉查找树
10 6 14 4 8 12 16
转化成排序的双向链表 结果为:
4==6==8==10==12==14==16