数据结构实验报告(二)——二叉树基本操作

数据结构实验报告(一)——线性表、堆栈和队列的操作与实现_队列的基本操作实验报告-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/luohaojia123/article/details/128689896?spm=1001.2014.3001.5501数据结构实验报告(三)——图的操作和实现_图的基本操作数据结构实验总结与体会(问题及解决方案、收获与感想等,不低于500字)-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/luohaojia123/article/details/128690098?spm=1001.2014.3001.5501数据结构实验报告(四)——查找和排序算法_查找算法的设计与实现实验报告-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/luohaojia123/article/details/128690401?spm=1001.2014.3001.5501

目录

  1.  结构体定义
  2. 先序创建二叉树
  3. 遍历
  4. 交换左右子树 
  5. 打印树 
  6. 查找结点
  7. 插入结点(叶子)
  8. 销毁树
  9. 树的深度
  10. 树的宽度
  11. 统计结点个数
  12. 每个叶子结点到根结点的路径

结构体定义

//定义二叉树的结构 
typedef char ElemType;
typedef struct BiTNode
{
    ElemType data;		//数据域 
    struct BiTNode* lchild, * rchild;	//左右子树 
} BiTNode, *BiTree;	//节点、整颗树 

先序创建二叉树

//先序创建二叉树
void CreateBiTree(BiTree *T){
	char ch;
	cin>>ch;
	if(ch=='#') *T=NULL;
	else{
		*T=new BiTNode;
		(*T)->data=ch;
		CreateBiTree(&((*T)->lchild));
		CreateBiTree(&((*T)->rchild));
	}
}

遍历

//先序遍历
void PreOrderTraverse(BiTree T){
	if(T){
		cout<<T->data;
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
	}
}
//中序遍历
void InOrderTraverse(BiTree T){
	if(T){
		PreOrderTraverse(T->lchild);
		cout<<T->data;
		PreOrderTraverse(T->rchild);
	}
}
//后序遍历
void PostOrderTraverse(BiTree T){
	if(T){
		PreOrderTraverse(T->lchild);
		PreOrderTraverse(T->rchild);
		cout<<T->data;
	}
}

打印树

//打印树 
void PrintTree(BiTree T,int deep,string code){
	//* @T 树的根节点
    //* @deep 此节点的深度
    //* @code 从根节点遍历到此处的路径码,向左用0表示,向右用1表示*/
	if(T){
		PrintTree(T->rchild,deep+1,code+"1");
		for(int i=0;i<deep;++i){
			cout<<(i==deep-1?(code[i]=='1'?"┌────":"└────"):(code[i]==code[i+1]?"     ":"│    "));
		}
		cout<<"("<<T->data<<")"<<endl;
		PrintTree(T->lchild,deep+1,code+"0"); 	
	}
}

查找节点

//查找节点
BiTree FindNode(BiTree T,ElemType x){
	BiTree tmp;
	if(T==NULL) return NULL;
	if(T->data==x) return T;
	else{
		tmp=FindNode(T->lchild,x);
		if(tmp) return tmp;
		tmp=FindNode(T->rchild,x);
		if(tmp) return tmp;
	}
} 

插入节点(叶子)

//插入节点
void AddNode(BiTree *T,int direction,ElemType x){
	if(direction==0){
		if((*T)->lchild==NULL){
			BiTNode *newNode=new BiTNode;
			newNode->data=x;
			newNode->lchild=NULL,newNode->rchild=NULL;
			(*T)->lchild=newNode;
		}else{
			AddNode(&((*T)->lchild),direction,x);
		}
	}else if(direction==1){
		if((*T)->rchild==NULL){
			BiTNode *newNode=new BiTNode;
			newNode->data=x;
			newNode->lchild=NULL,newNode->rchild=NULL;
			(*T)->rchild=newNode;
		}else{
			AddNode(&((*T)->rchild),direction,x);
		}
	}
}

树的深度

//树的深度
int Depth(BiTree T){
	if(T==NULL) return 0;
	else{
		int i=Depth(T->lchild);
		int j=Depth(T->rchild);
		return i>j ? i+1 : j+1;
	}
}

树的宽度

//求每一层的宽度
void LawyerWidth(BiTree T,int a[],int h){
	if(T){
		a[h]++;
		LawyerWidth(T->lchild,a,h+1);
		LawyerWidth(T->rchild,a,h+1);
	}
}
//树的宽度
int Width(BiTree T){
	int H=Depth(T);		   //总高度 
	int *a=new int[H+1];
	for(int i=0;i<H+1;i++){
		a[i]=0;
	}
	 
	int h=1;	//当前高度 
	LawyerWidth(T,a,h);	   //求每一层的宽度 
	
	int width=a[0];
	for(int i=1;i<H+1;++i){	//取最大宽度作为树的宽度 
		if(a[i]>width) width=a[i];
	}
	return width;
}

统计节点个数

//统计结点个数
int NodeCount(BiTree T){
	if(T==NULL) return 0;
	else{
		return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;
	}
} 

每个叶子节点到根节点的路径

//每个叶子节点到根结点的路径
void PrintAllPath(BiTree T,char path[],int pathlen){
	int i;
	if(T){
		path[pathlen] = T->data;
		if(T->lchild==NULL && T->rchild==NULL){
			for(i=pathlen;i>=0;i--){	//倒叙输出 
				cout<<path[i]<<" ";
			}
			cout<<endl;
		} else{
			PrintAllPath(T->lchild,path,pathlen+1);
			PrintAllPath(T->rchild,path,pathlen+1);
		}
	}
}

main函数

int main(){
	BiTree Tree=NULL;
	
	CreateBiTree(&Tree);	//初始化
	cout<<"------初始化------"<<endl; 
	cout<<"先序遍历: ";
	PreOrderTraverse(Tree);
	cout<<endl; 
	cout<<"中序遍历: "; 
	InOrderTraverse(Tree);
	cout<<endl;
	cout<<"后序遍历: "; 
	PostOrderTraverse(Tree);
	cout<<endl;
	PrintTree(Tree);	//打印树形 
	cout<<endl;
	
	cout<<"------交换左右子树------"<<endl; 
	ChangeBiTree(Tree);
	cout<<"先序遍历: ";
	PreOrderTraverse(Tree);
	cout<<endl;
	PrintTree(Tree);	//打印树形 
	cout<<endl;
	
	cout<<"------插入结点------"<<endl;
	BiTree find=FindNode(Tree,'B');
	AddNode(&find,0,'S');
	AddNode(&Tree,1,'Z');
	cout<<"先序遍历: ";
	PreOrderTraverse(Tree);
	cout<<endl;
	PrintTree(Tree);	//打印树形
	cout<<endl; 
	
	
	cout<<"------其他信息------"<<endl;
	cout<<"树的深度:";
	cout<<Depth(Tree)<<endl;
	cout<<"树的宽度:";
	cout<<Width(Tree)<<endl;
	cout<<"树的结点个数:";
	cout<<NodeCount(Tree)<<endl;
	cout<<"二叉树中从每个叶子结点到根结点的所有路径:"<<endl;
	char path[256];	//存放路径 
	int pathlen=0;	//路径长度初始为0 
	PrintAllPath(Tree,path,pathlen);
	
	DestroyBitree(&Tree);	//销毁树 
	
	return 0;
}

运行结果

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值