目录
用字符串构建一棵二叉树(输入扩展二叉树的前序序列,输出中序)
判断两棵二叉树是否结构相同(给定前序,构建二棵二叉树,判断是否相同)
线索二叉树(输入前序,输出中序并销毁二叉树)
【问题描述】
建立线索链表,实质上就是将二叉链表中的空指针改为指向前驱或后继的线索,而前驱或后继的信息只有在遍历该二叉树时才能得到。给定扩展二叉树的前序序列,构建二叉树。然后为这棵二叉树建立中序线索链表,并利用线索链表输出中序遍历结果。
【输入形式】
输入扩展二叉树的前序序列。
【输出形式】
利用线索二叉树输出树的中序遍历序列,并且按照中序顺序输出销毁线索二叉树的过程。
【样例输入】
abd#g###ce##f##
【样例输出】
Inorder:dgbaecf
Inorder finished. Calling destructer...
delete d
delete g
delete b
delete a
delete e
delete c
delete f
【题目要求】
要求创建二叉树,然后建立线索链表
【题解代码】
#include<iostream>
#include<stdio.h>
using namespace std;
struct ThreadNode
{
char data;
ThreadNode *lchild, *rchild;
int ltag, rtag;
};
class ThreadBiTree
{
private:
ThreadNode *root;//指向线索链表的头指针
public:
ThreadBiTree() //构造函数,建立中序线索链表
{
root = NULL;
root = creat(root);
inThread(root);
}
~ThreadBiTree(); //析构函数,释放各结点的存储空间
ThreadNode *next(ThreadNode *p); //查找p的后继
void inOrder(); //中序遍历线索链表
private:
ThreadNode *creat(ThreadNode *bt);
void destroy(ThreadNode *p); //线索化,由构造函数调用
void inThread(ThreadNode *p); //线索化,由构造函数调用
};
//create函数创建二叉树
ThreadNode *ThreadBiTree::creat(ThreadNode *bt)
{
//在此处填写创建线索二叉树的代码
char ch;
cin >> ch;
if (ch == '#')
bt = NULL;
else
{
bt = new ThreadNode;
bt->data = ch;
bt->ltag = 0;
bt->rtag = 0;
bt->lchild = creat(bt->lchild);
bt->rchild = creat(bt->rchild);
}
return bt;
}
//实现二叉树线索化,这个函数由构造函数调用
void ThreadBiTree::inThread(ThreadNode *p)
{
//在此处填写建立二叉树线索化的代码,注意,这个函数跟其他函数不同,它 的函数头可以修改,注意检查大括号是否匹配
static ThreadNode* pre = NULL;//保存上一次递归遍历的结果
if (p == NULL)
return;
inThread(p->lchild);
if (p->lchild == NULL)
{
p->ltag = 1;
p->lchild = pre;
}
if (pre != NULL && pre->rchild == NULL)
{
pre->rtag = 1;
pre->rchild = p;
}
pre = p;
inThread(p->rchild);
}
//查找p的后继
ThreadNode* ThreadBiTree::next(ThreadNode *p)
{
//在此处填写next函数的代码
ThreadNode* q;
if (p->rtag == 1)
q = p->rchild;
else
{
q = p->rchild;
while (q->ltag == 0)
q = q->lchild;
}
return q;
}
//中序遍历线索链表
void ThreadBiTree::inOrder()
{
//在此处填写中序遍历线索二叉树的代码
if (root == NULL)
return;
ThreadNode* p = root;
while (p->ltag == 0)
{
p = p->lchild;
}
cout << p->data;
while (p ->rchild!= NULL)
{
p = next(p);
cout << p->data;
}
}
//析构函数,释放各结点的存储空间
//这个要注意,和普通的析构函数不一样
ThreadBiTree::~ThreadBiTree() //卡了好久
{
//在此处填写销毁线索二叉树的代码
ThreadNode *p,*q;
p=root;
while(p->ltag==0)
{
p=p->lchild;
}
q=p;
while(p->rchild!=NULL)
{
cout<<"delete "<<p->data<<endl;
p=next(p);
delete q;
q=p;
}
cout<<"delete "<<p->data<<endl;
delete p;
}
int main()
{
ThreadBiTree tree;
cout << "Inorder:";
tree.inOrder();
cout << endl << "Inorder finished. Calling destructer..."<<endl;
return 0;
}
//好累,不写每一句的注释了
用字符串构建一棵二叉树(输入扩展二叉树的前序序列,输出中序)
【问题描述】
输入一组扩展二叉树的前序序列存入字符串,然后构建一棵二叉树。输出这棵二叉树的中序遍历序列。
【输入形式】
输入扩展二叉树的前序序列。
【输出形式】
输出二叉树的中序遍历序列。
【样例输入】
ab##cd##e##
【样例输出】
badce
【题目要求】
要求在递归函数中传入保存扩展二叉树前序序列的字符串。
【题解代码】
/**用前序字符串创建树*/
#include<iostream>
#include<stdio.h>
#include<string.h>
const int MAX=1000;
using namespace std;
struct BiNode
{
char data;//数据域
BiNode *lchild, *rchild;//左右儿子指针
};
class BiTree
{
private:
BiNode *root; //指向根结点的头指针
public:
BiTree()
{
root = NULL; //无参构造函数,创建空的二叉树
}
BiTree(char str[])
{
int index = 0;
root = creat(root,str,index); //有参构造函数,利用已有的串构建二叉树
}
~BiTree()
{
release(root);
}
BiNode* getRoot()
{
return root;
}
void setRoot(BiNode* bt)
{
root = bt;
}
BiNode* creat(BiNode *bt, char str[], int &index); //构造函数调用
void release(BiNode *bt); //析构函数调用,释放树的存储空间
void inOrder(BiNode *bt); //中序遍历函数调用
};
/**利用已有的字符串前序构建二叉树*/
BiNode *BiTree::creat(BiNode *bt, char str[], int &index)
{
if(str[index]=='#'||str[index]=='\0')
{
bt=NULL;
if(str[index]=='\0')
{
index--;
}
}
else
{
bt=new BiNode;
bt->data=str[index];
index++;
bt->lchild=creat(bt->lchild,str,index);
index++;
bt->rchild=creat(bt->rchild,str,index);
}
return bt;
//以下注释掉的是一个差不多的写法
/*
if(str[index]=='\0'){
bt=NULL;}
else if(str[index]=='#'){
index++;
bt=NULL;}
else{
bt=new BiNode;
bt->data=str[index];
index++;
bt->lchild=creat(bt->lchild,str,index);
bt->rchild=creat(bt->rchild,str,index);
}
return bt;
*/
}
/**后序释放二叉树节点*/
void BiTree::release(BiNode *bt)
{
if(bt==NULL)
{
return;
}
else
{
release(bt->lchild);
release(bt->rchild);
}
}
/**中序遍历*/
void BiTree::inOrder(BiNode * bt)
{
if(bt==NULL)
{
return;
}
else
{
inOrder(bt->lchild);
cout<<bt->data;
inOrder(bt->rchild);
}
}
int main()
{
//cout<<"输入前序字符串:";
char str[MAX];
cin >> str;
BiTree tree(str);
tree.inOrder(tree.getRoot());
return 0;
}
设计算法复制一棵二叉树(给定前序,复制,输出中序)
【问题描述】
编写代码复制一棵二叉树。首先给定一组扩展二叉树的前序序列,构建一棵二叉树。然后编写代码复制这棵二叉树,并输出目标二叉树的中序遍历序列。
【输入形式】
输入扩展二叉树的前序序列。
【输出形式】
分两行输出两棵二叉树的中序遍历序列
【样例输入】
ab##cd##e##
【样例输出】
Copy Finished!
InOrder:badce
【题目要求】
要求创建名为source的二叉树对象,输入扩展二叉树的前序序列,构建一棵二叉树;然后创建名为dest的空树(输入#,则创建空树);然后在指定的函数框架中填写二叉树的复制代码,最后目标二叉树进行中序遍历。
【题解代码】
/**用复制一棵树,用字符串构建树*/
#include<iostream>
#include<stdio.h>
#include<string.h>
const int MAX=1000;
using namespace std;
struct BiNode
{
char data;//数据域
BiNode *lchild, *rchild;//左右儿子指针
};
class BiTree
{
private:
BiNode *root; //指向根结点的头指针
public:
BiTree() //无参构造函数,创建空的二叉树
{
root = NULL;
}
BiTree(char str[]) //有参构造函数,利用已有的串构建二叉树
{
int index = 0;
root = creat(root,str,index);
}
~BiTree()
{
release(root);
}
BiNode* getRoot() //getter
{
return root;
}
void setRoot(BiNode* bt) //setter
{
root = bt;
}
void inOrder()
{
inOrder(root);
}
private:
BiNode* creat(BiNode *bt, char str[], int &index); //构造函数调用
void release(BiNode *bt); //析构函数调用,释放树的存储空间
void inOrder(BiNode *bt); //中序遍历函数调用
};
/**利用已有的字符串前序构建二叉树*/
BiNode *BiTree::creat(BiNode *bt, char str[], int &index) //跟上一个题一样
{
if(str[index]=='#'||str[index]=='\0')
{
bt=NULL;
if(str[index]=='\0')
{
index--;
}
}
else
{
bt=new BiNode;
bt->data=str[index];
index++;
bt->lchild=creat(bt->lchild,str,index);
index++;
bt->rchild=creat(bt->rchild,str,index);
}
return bt;
}
/**后序释放二叉树节点*/
void BiTree::release(BiNode *bt)
{
if(bt==NULL)
{
return;
}
else
{
release(bt->lchild);
release(bt->rchild);
}
}
/**中序遍历*/
void BiTree::inOrder(BiNode * bt)
{
if(bt==NULL)
{
return;
}
else
{
inOrder(bt->lchild);
cout<<bt->data;
inOrder(bt->rchild);
}
}
/*//------------分割线 普通函数------------------//*/
/* 复制一棵树
// 参数说明:传入源树和目的树的根节点指针
注意,这里dest这个指针的值需要传出去,因此采用引用&,否则不能传回。
*/
void copyTree(BiNode *source, BiNode* &dest)
{
if (source == NULL)
{
dest = NULL;
return;
}
dest = new BiNode;
dest->data = source->data;
copyTree(source->lchild, dest->lchild);
copyTree(source->rchild, dest->rchild);
}
int main()
{
char str[MAX];
BiNode *dest=NULL,*source=NULL; //指向两棵树的根节点的指针
// cout << "请输入一棵树:(形式为:ABD##E##CF###)"<<endl;
cin >> str;
BiTree sourceTree(str);
source = sourceTree.getRoot();
BiTree destTree; //创建一棵空树
copyTree(source,dest);
destTree.setRoot(dest); //把复制后的树的指针存储到destTree类中
cout <<"Copy Finished!"<<endl;
cout <<"InOrder:";
destTree.inOrder();
return 0;
}
判断两棵二叉树是否结构相同(给定前序,构建二棵二叉树,判断是否相同)
【问题描述】
给定两组扩展二叉树的前序序列,构建两棵二叉树。判断这两棵二叉树结构是否相同?
【输入形式】
分两行分别输入两棵扩展二叉树的前序序列。
【输出形式】
如果两个二叉树结构相同,输出“Same structure.”;如果两个二叉树结构不相同,输出“Different structure.”
【样例输入】
ab##cd##e##
AF##DE##K##
【样例输出】
Same structure.
【题目要求】
要求创建二叉树,然后用函数判断两棵二叉树是否相同。
【题解代码】
/**字符串建树判断两棵二叉树是否结构相同*/
#include<iostream>
#include<stdio.h>
using namespace std;
struct BiNode
{
char data;//数据域
BiNode *lchild, *rchild;//左右儿子指针
};
class BiTree
{
private:
BiNode *root; //指向根结点的头指针
public:
BiTree()
{
root = NULL;
root = creat(root);//调函数构建二叉树
}
~BiTree()
{
release(root);
}
BiNode * getRoot()
{
return root;
}
BiNode *creat(BiNode *bt); //构造函数调用
void release(BiNode *bt); //析构函数调用,释放树的存储空间
};
/**前序构建二叉树*/
BiNode *BiTree::creat(BiNode *bt)
{
char ch;
cin>>ch;
if(ch=='#')
bt = NULL;
else
{
bt = new BiNode;
bt->data = ch;
bt->lchild = creat(bt->lchild);
bt->rchild = creat(bt->rchild);
}
return bt;
}
/**后序释放二叉树节点*/
void BiTree::release(BiNode *bt)
{
if(bt==NULL)
{
return;
}
else
{
release(bt->lchild);
release(bt->rchild);
}
}
/*
isSameStructure函数
功能:接收两棵树的根节点指针,用来判断两棵树的结构是否相同
*/
bool isSameStructure(BiNode * bt1, BiNode * bt2)
{
if (bt1 == NULL && bt2 == NULL)
{
return true;
}
if (bt1 == NULL || bt2 == NULL)
{
return false;
}
return isSameStructure(bt1->lchild, bt2->lchild) && isSameStructure(bt1->rchild, bt2->rchild); //这里分开写更好看
//bool left=isSameStructure(bt1->lchild, bt2->lchild) ;
//bool right=isSameStructure(bt1->rchild, bt2->rchild);
//return (left&&right);
}
int main()
{
BiNode *root1,*root2;
BiTree tree1;
root1 = tree1.getRoot();
BiTree tree2;
root2 = tree2.getRoot();
if(isSameStructure(root1,root2))
{
cout << "Same structure."<< endl;
}
else
{
cout << "Different structure." <<endl;
}
return 0;
}