您的位置:首页 > 其它

【July第1题】二叉排序树转换成双链表

2012-12-16 00:17 218 查看
/************************************************************************/
/*
题目:要求在不创造新的节点的情况下,把二叉排序树转成双向链表。只能靠转换链接来实。
思路一:利用二叉排序树中序遍历的思路解题,一种将问题分解成不断链接到尾部
思路二:一种将问题分解成左右链表,将结点链接到前驱和后继链表
作者:akon
时间:2012/12/16
*/
************************************************************************/

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

typedef struct BSTreeNode{
int data;
BSTreeNode* lchild;
BSTreeNode* rchild;

}*BStree;

void CreateTree(BStree& T);
void Insert(BStree& T,const int data);
void InOrderDisplay(BStree T);

void Convert(BStree T,BSTreeNode* &pTail);
BSTreeNode* Convert2(BSTree T);

void CreateTree(BStree& T)
{
int data;
string line;
getline(cin,line);//from string header
istringstream iss(line);
iss>>data;
T=new BSTreeNode;
T->data=data;
T->lchild=NULL;
T->rchild=NULL;
while(iss>>data){
Insert(T,data);
}

}
void Insert(BStree& T,const int data)
{
if(T==NULL){
BSTreeNode* node=new BSTreeNode;
node->data=data;
node->lchild=NULL;
node->rchild=NULL;
T=node;
return;
}
if(data>T->data){
Insert(T->rchild,data);
}
else
Insert(T->lchild,data);
}
void InOrderDisplay(BStree T)
{//这里给出中序遍历是为了和下面方法对比
if(T==NULL)
return;
if(T->lchild!=NULL)
InOrderDisplay(T->lchild);
cout<<T->data<<'\t';
if(T->rchild!=NULL)
InOrderDisplay(T->rchild);
}
/*
易知,二叉排序树的中序输出即为有序输出,所以可从这个角度出发。
递归假设:左树已经转换好,并保存链表的尾部结点
递归操作:将当前结点链接到已经转换的链表,再转右部分
*/
void Convert(BStree T,BSTreeNode*& pTail)
{
//递归终止条件
if(T==NULL)
return;
//先转左
if(T->lchild!=NULL)
Convert(T->lchild,pTail);
//此递归的假设是左边已经转换,此时pTail是左边转好的双链表的尾结点,故将当前结点添加到链表尾部
T->lchild=pTail;
//有可能这是首个结点,也就是二叉树的最左结点(最小值),这种情况下不需要pTail还为NULL
if(pTail!=NULL)
pTail->rchild=T;
//移动尾结点
pTail=T;
//最后转右
if(T->rchild!=NULL)
Convert(T->rchild,pTail);
}
/*
方法二:
将二叉树分成两端考虑,左双链表和右双链表
递归:操作,将此结点链接到左右两端
*/
BSTreeNode* Convert2(BStree T)
{
if(T==NULL)
return NULL;

BSTreeNode* pLeft=NULL;
BSTreeNode* pRight=NULL;

if(T->lchild)
pLeft=Convert2(T->lchild);
if(pLeft!=NULL){
pLeft->rchild=T;
T->lchild=pLeft;
}
if(T->rchild)
pRight=Convert2(T->rchild);
if(pRight){
T->rchild=pRight;
pRight->lchild=T;
}
}

void TestConvert1(BStree tree)
{
BSTreeNode* pTail=NULL;
Convert(tree,pTail);
//根据尾找到头
BSTreeNode* pHead=pTail;
while(pHead->lchild)pHead=pHead->lchild;
BSTreeNode* temp=pHead;

cout<<"双向链表正向输出:"<<endl;
while(temp){
cout<<temp->data<<'\t';
temp=temp->rchild;
}
cout<<endl;

cout<<"双向链表逆向输出:"<<endl;
temp=pTail;
while(temp){
cout<<temp->data<<'\t';
temp=temp->lchild;
}
cout<<endl;

}
void TestConvert2(BStree tree)
{
BSTreeNode* pTail;
BSTreeNode* pHead;
pTail=Convert2(tree);
pHead=pTail;

while(pHead->lchild) pHead=pHead->lchild;
while(pTail->rchild) pTail=pTail->rchild;
BSTreeNode* temp=pHead;

cout<<"双向链表正向输出:"<<endl;
while(temp){
cout<<temp->data<<'\t';
temp=temp->rchild;
}
cout<<endl;

cout<<"双向链表逆向输出:"<<endl;
temp=pTail;
while(temp){
cout<<temp->data<<'\t';
temp=temp->lchild;
}
cout<<endl;
}

int main()
{
cout<<"请输入构造树的整数值: "<<endl;
BStree tree=NULL;
CreateTree(tree);
cout<<"二叉查找树的前序遍历结果是:"<<endl;
InOrderDisplay(tree);
cout<<endl;
TestConvert1(tree);

cout<<"请输入构造树的整数值: "<<endl;
BStree tree2;
CreateTree(tree2);
cout<<"二叉查找树的前序遍历结果是:"<<endl;
InOrderDisplay(tree2);
cout<<endl;
TestConvert2(tree2);
system("pause");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: