编译器是DevC++。可能有地方写得不够规范,大佬轻喷。
//链式存储的二叉树
//先序建立方式
//遍历方式:先序,中序,后序,层次
//计算:树的深度,叶子节点,节点数,度为1的节点数,度为2的节点数
//二叉树的复制,交换左右子树
//二叉树的查找,修改,删除,插入
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
int n;
typedef struct Node{
int data;
Node *lchild,*rchild;
}LkNode,*BiTree;
void CreateBiTree(BiTree &T){
int inputdata;
cin>>inputdata;
if(inputdata == -1){
T = NULL;
//return;
}
else{
T = new LkNode();
if(!T)
cout<<"开辟空间失败!"<<endl;
else{
T ->data = inputdata; //创建根节点
CreateBiTree(T ->lchild);
CreateBiTree(T ->rchild);
}
}
}
void PreOrederTraverse(BiTree T){ //递归实现先序遍历
if(T != NULL){
cout<<T ->data<<" ";
PreOrederTraverse(T ->lchild);
PreOrederTraverse(T ->rchild);
}
else{
//cout<<"二叉树为空!"<<endl;
return;
}
}
void MidOrederTraverse(BiTree T){ //递归实现中序遍历
if(T != NULL){
MidOrederTraverse(T ->lchild);
cout<<T ->data<<" ";
MidOrederTraverse(T ->rchild);
}
else{
//cout<<"二叉树为空!"<<endl;
return;
}
}
void LastOrederTraverse(BiTree T){ //递归实现后序遍历
if(T != NULL){
LastOrederTraverse(T ->lchild);
LastOrederTraverse(T ->rchild);
cout<<T ->data<<" ";
}
else{
//cout<<"二叉树为空!"<<endl;
return;
}
}
void LevelTraverse(BiTree T){ //队列实现层次遍历
queue<BiTree> que;
if(T != NULL){
while(T){
cout << T->data << " ";
if(T->lchild)
que.push(T->lchild);
if(T->rchild)
que.push(T->rchild);
if(que.empty())
break;
T = que.front(); //将队列首元素赋予T,
que.pop();
}
}
else{
//cout<<"二叉树为空!"<<endl;
return;
}
}
int DepthBiTree(BiTree T){ //计算二叉树的深度
int dep = 0,depl,depr;
if(!T)
return 0;
else{
depl = DepthBiTree(T ->lchild);
depr = DepthBiTree(T ->rchild);
dep = 1 + (depl > depr ? depl : depr);
return dep;
}
}
int NodeCount(BiTree T){ //计算节点数
int nodecount = 0;
if(!T)
return 0;
else{
//return NodeCount(T ->lchild) +NodeCount(T ->rchild) + 1;
nodecount++;
nodecount += NodeCount(T ->lchild);
nodecount += NodeCount(T ->rchild);
}
return nodecount;
}
int LeafCount(BiTree T){ //计算叶子节点数
int leafcount = 0;
if(!T)
return 0;
else{
if( (!T ->lchild) && (!T ->rchild) ) //左右子树均为空,则为叶子节点
//leafcount++; //两种写法都可以
leafcount = 1;
leafcount += LeafCount(T ->lchild);
leafcount += LeafCount(T ->rchild);
}
return leafcount;
}
int SinglePointCount(BiTree T){ //计算度为1的节点数
int sgcount = 0;
if(!T)
return 0;
else{
if( T ->lchild && T ->rchild ){ //左右节点都不为空,则分别计算左右子树度为1的节点个数
sgcount += SinglePointCount(T ->lchild);
sgcount += SinglePointCount(T ->rchild);
}
if( T ->lchild && (!T ->rchild) ){ //左节点不为空,计算左子树度为1的节点个数
sgcount++;
sgcount += SinglePointCount(T ->lchild);
}
if( (!T ->lchild) && T ->rchild ){ //右节点不为空,计算右子树度为1的节点个数
sgcount++;
sgcount += SinglePointCount(T ->rchild);
}
}
return sgcount;
}
int DoublePointCount(BiTree T){ //计算度为2的节点数
int dbcount = 0;
if(!T)
return 0;
else{
if( T ->lchild && T ->rchild ) //左右子树均不为空,则度为2
dbcount++;
dbcount += DoublePointCount(T ->lchild);
dbcount += DoublePointCount(T ->rchild);
}
return dbcount;
}
void SwapBiTree(BiTree &T){ //交换左右子树所有节点
BiTree tem = new LkNode();
if(T){
tem = T ->rchild;
T ->rchild = T ->lchild;
T ->lchild = tem;
SwapBiTree(T ->lchild);
SwapBiTree(T ->rchild);
}
else return;
}
void CopyBiTree(BiTree T,BiTree &T2){ //复制二叉树
T2 = new LkNode();
if(T){
T2 ->data = T ->data;
CopyBiTree(T ->lchild,T2 ->lchild);
CopyBiTree(T ->rchild,T2 ->rchild);
}
else{
T2 = NULL;
return;
}
}
bool SearchNode(BiTree T,int search){ //查找节点
if(T){
if(T ->data == search){
cout<<"节点"<<search<<"存在,";
if(T ->lchild && T ->rchild){
cout<<"且节点"<<search<<"的左孩子为"<<T ->lchild ->data;
cout<<",右孩子为"<<T ->rchild ->data<<"。"<<endl;
}
else if(T ->lchild && (!T ->rchild)){
cout<<"且节点"<<search<<"的左孩子为"<<T ->lchild ->data;
cout<<",右孩子为空。"<<endl;
}
else if((!T ->lchild) && T ->rchild){
cout<<"且节点"<<search<<"的左孩子为空";
cout<<",右孩子为"<<T ->rchild ->data<<"。"<<endl;
}
else
cout<<"该节点无左右孩子。"<<endl;
return true;
}
else{
bool flag = SearchNode(T ->lchild,search);
if(flag)
{}
else
SearchNode(T ->rchild,search);
}
}
else
return false;
}
void GetParent(BiTree T,int search){ //查找父节点
if(T ->lchild){
if(T ->lchild ->data == search){
cout<<"节点"<<search<<"为父节点"<<T ->data<<"的左孩子。"<<endl;
return;
}
else
GetParent(T ->lchild,search);
}
if(T ->rchild){
if(T ->rchild ->data == search){
cout<<"节点"<<search<<"为父节点"<<T ->data<<"的右孩子。"<<endl;
return;
}
else
GetParent(T ->rchild,search);
}
if( (!T ->lchild) && (!T ->rchild) )
return;
}
bool UpdateNode(BiTree &T,int update){ //修改节点
if(T){
if(T ->data == update){
int update2;
cout<<"节点"<<update<<"存在,请输入更改后的数据:";
cin>>update2;
T ->data = update2;
return true;
}
else{
bool flag = UpdateNode(T ->lchild,update);
if(flag)
{}
else
UpdateNode(T ->rchild,update);
}
}
else
return false;
}
bool DeleteNode(BiTree &T,int dlt){ //删除节点
if(T){
if(T ->data == dlt){
if(T ->lchild && T ->rchild){ //用左孩子替代原节点,右孩子变成左孩子的左孩子
BiTree tem = T ->rchild;
T = T ->lchild; //可以写个if,左右节点谁大谁替代原节点
T ->lchild = tem;
T ->rchild = NULL;
}
else if(T ->lchild && (!T ->rchild)){ //用左孩子替代原节点
T = T ->lchild;
}
else if((!T ->lchild) && T ->rchild){ //用右孩子替代原节点
T = T ->rchild;
}
else
T = NULL;
//T = NULL; //连同左右孩子一起删除
return true;
}
else{
bool flag = DeleteNode(T ->lchild,dlt);
if(flag)
{}
else
DeleteNode(T ->rchild,dlt);
}
}
else
return false;
}
bool InsertNode(BiTree &T,int istparent){ //删除节点
if(T){
if(T ->data == istparent){
int istdata;
if(T ->lchild && T ->rchild){ //选择插入为原节点的左孩子或右孩子
cout<<"父节点左右孩子均存在,输入0代表插入为左孩子,输入1代表插入为右孩子。";
cout<<endl<<"(其它视为空插入)请输入:";
int lr;
cin>>lr;
if(lr == 0){
cout<<"请输入要插入的数据:";
cin>>istdata;
BiTree tem = new LkNode(); //开辟新空间
tem ->data = istdata;
tem ->lchild = T ->lchild; //插入后原节点的左孩子,变成现节点的左孩子
tem ->rchild = NULL;
T ->lchild = tem;
}
else if(lr == 1){
cout<<"请输入要插入的数据:";
cin>>istdata;
BiTree tem = new LkNode();
tem ->data = istdata;
tem ->rchild = T ->rchild; //插入后原节点的右孩子,变成现节点的右孩子
tem ->lchild = NULL;
T ->rchild = tem;
}
else
cout<<"插入为空。"<<endl;
}
else if(T ->lchild && (!T ->rchild)){ //插入为原节点的右孩子
cout<<"父节点左孩子存在,右孩子为空,默认插入为右孩子,请输入要插入的数据:";
cin>>istdata;
BiTree tem = new LkNode();
tem ->data = istdata;
T ->rchild = tem;
}
else if((!T ->lchild) && T ->rchild){ //插入为原节点的左孩子
cout<<"父节点左孩子为空,右孩子存在,默认插入为左孩子,请输入要插入的数据:";
cin>>istdata;
BiTree tem = new LkNode();
tem ->data = istdata;
T ->lchild = tem;
}
else{
cout<<"父节点左右孩子均不存在,默认插入为左孩子,请输入要插入的数据:";
cin>>istdata;
BiTree istl = new LkNode();
istl ->data = istdata;
//istl ->lchild = NULL;
//istl ->rchild = NULL;
T ->lchild = istl;
}
return true;
}
else{
bool flag = InsertNode(T ->lchild,istparent);
if(flag)
{}
else
InsertNode(T ->rchild,istparent);
}
}
else
return false;
}
int main(){
while(1){
BiTree tree = NULL; //创建从根节点开始的二叉树
cout<<"请输入二叉树tree的节点:";
CreateBiTree(tree);
cout<<"二叉树tree创建成功!"<<endl;
cout<<"先序遍历的顺序为:";
PreOrederTraverse(tree);
cout<<endl;
cout<<"中序遍历的顺序为:";
MidOrederTraverse(tree);
cout<<endl;
cout<<"后序遍历的顺序为:";
LastOrederTraverse(tree);
cout<<endl;
cout<<"层次遍历的顺序为:";
LevelTraverse(tree);
cout<<endl;
cout<<"二叉树tree的深度为:"<<DepthBiTree(tree)<<endl;
cout<<"二叉树tree的节点数为:"<<NodeCount(tree)<<endl;
cout<<"其中:"<<endl;
cout<<"叶子节点数为:"<<LeafCount(tree)<<endl;
cout<<"度为1的节点数为:"<<SinglePointCount(tree)<<endl;
cout<<"度为2的节点数为:"<<DoublePointCount(tree)<<endl;
BiTree tree2 = NULL;
CopyBiTree(tree,tree2);
cout<<"将二叉树tree复制到tree2后,tree2层次遍历的顺序为:";
LevelTraverse(tree2);
cout<<endl;
SwapBiTree(tree2);
cout<<"交换tree2左右子树所有结点后,tree2层次遍历的顺序为:";
LevelTraverse(tree2);
cout<<endl;
int srh;
cout<<"请输入tree中你要查找的节点:";
cin>>srh;
if(SearchNode(tree,srh)){
if(tree ->data == srh)
cout<<"节点"<<srh<<"为根节点,无父节点。"<<endl;
else
GetParent(tree,srh);
}
else
cout<<"查找节点不存在!"<<endl;
int upt;
cout<<"请输入tree中你要更改的节点:";
cin>>upt;
if(UpdateNode(tree,upt)){
cout<<"修改成功!修改后tree层次遍历的顺序为:";
LevelTraverse(tree);
cout<<endl;
}
else
cout<<"修改节点不存在!"<<endl;
int dlt;
cout<<"请输入tree中你要删除的节点:";
cin>>dlt;
if(DeleteNode(tree,dlt)){
cout<<"删除成功!删除后tree层次遍历的顺序为:";
LevelTraverse(tree);
cout<<endl;
}
else
cout<<"删除节点不存在!"<<endl;
int istparent;
cout<<"请输入tree中你要插入节点的父节点:";
cin>>istparent;
if(InsertNode(tree,istparent)){
cout<<"插入成功!插入后tree层次遍历的顺序为:";
LevelTraverse(tree);
cout<<endl;
}
else
cout<<"要插入节点的父节点不存在!"<<endl;
}
}
/*测试样例:
1 2 4 8 -1 -1 -1 5 9 -1 -1 10 14 -1 -1 15 -1 -1 3 6 11 -1 -1 12 -1 -1 7 -1 13 -1 -1
*/