题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能创建任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。
首先我们定义的二元查找树 节点的数据结构如下:
struct BSTreeNode
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
本题算法的思想是:将root根结点的右子树的最小值 和root 互指,将root的左子树最大值结点和 root 互指。以此对左右结点递归,完成了二叉树到双向链表转换。
vs2008编译环境:
tree.h文件如下:
using namespace std;
struct binaryTree
{
int val;
binaryTree *left;
binaryTree *right;
binaryTree(int t);
};
binaryTree::binaryTree(int t)
{
val=t;
left=right=NULL;
}
main.cpp文件如下:
#include<iostream>
#include"tree.h"
#include<queue>
using namespace std;
binaryTree *findLeft(binaryTree * temp)
{
while(temp->left)
temp=temp->left;
return temp;
}
binaryTree *findRight(binaryTree * temp)
{
while(temp->right)
temp=temp->right;
return temp;
}
void translate(binaryTree * temp)
{
//注释部分为中序遍历内容
/*
if(temp->left==NULL ) ;
else
translate(temp->left);
cout<<temp->val<<" ";
if(temp->right==NULL ) ;
else
translate(temp->right);
*/
if(temp==NULL) return;
binaryTree * t;
if(temp->left){
translate(temp->left);
t=findRight(temp->left);
t->right=temp;
temp->left=t;
}
if(temp->right){
translate(temp->right);
t=findLeft(temp->right);
t->left=temp;
temp->right=t;
}
}
void init()//二元查找树转双向链表
{
binaryTree *root=new binaryTree(10);
binaryTree * temp=new binaryTree(6);
root->left=temp;
temp->left=new binaryTree(4);
temp->right=new binaryTree(8);
temp=new binaryTree(14);
root->right=temp;
temp->left=new binaryTree(12);
temp->right=new binaryTree(16);
translate(root);
binaryTree* t;
t=root;
while(t->left){
t=t->left;
}
cout<<t->val<<" ";
//从左到右验证一次
while(t->right){
t=t->right;
cout<<t->val<<" ";
}
cout<<endl;
//从右到左验证一次
cout<<t->val<<" ";
while(t->left){
t=t->left;
cout<<t->val<<" ";
}
}
int main()
{
init();
system("pause");
return 0;
}