数据结构(2)——二叉树操作设计和实现

实验目标

(1)掌握二叉树的定义、性质及存储方式;
(2)掌握二叉树的各种遍历算法。

实验要求

(1)采用二叉树链表作为存储结构,完成二叉树的建立;
(2)提供对二叉树的先序、中序和后序以及按层次遍历的操作;
(3)提供求所有叶子及结点总数的操作。

开发环境

(1)开发语言:C语言或C++语言;
(2)操作系统:Windows、Linux、Mac OS等均可;
(3)开发IDE:工具不限,推荐使用CodeBlocks和Dev C++。

实验完整代码

#include"stdio.h"
#include"stdlib.h"
#include"string.h"
#define Max 20						//结点的最大个数
typedef struct node{
char data;
struct node *lchild, *rchild;
}BinTNode;							//自定义二叉树的结点类型
typedef BinTNode *BinTree;			//定义二叉树的指针
int NodeNum,leaf;					//NodeNum为结点数,leaf为叶子数,其实并没有用到这两个定义
typedef struct{
    BinTree base[100];
    int front,rear;
}SqQueue;	//为了后面层序遍历做准备,定义一个队列


BinTree CreateBinTree(void);		//基于先序遍历算法创建二叉树
void Preorder(BinTree T)	;			//先序遍历二叉树
void Inorder(BinTree T)		;		//中序遍历二叉树
void Postorder(BinTree T)	;		//后序遍历二叉树
int TreeDepth(BinTree T)	;			//采用后序遍历求二叉树的深度、结点数及叶子数的递归算法
void Levelorder(BinTree T)	;		//层次遍历二叉树
int countleaf(BinTree T)	;	       //数叶子节点个数
int NodeCount(BinTree T)    ;      //数所有节点个数【原来没有这个函数】

/*****************************/
/*          主函数           */
/*****************************/
void main()
{
BinTree root;
char i;
int depth;
printf("\n");
printf("Creat Bin_Tree; Input preorder:");	//输入完全二叉树的先序序列,用#代表虚结点,如ABD###CE##F##
root=CreateBinTree();							//创建二叉树,返回根结点
do {											//从菜单中选择遍历方式,输入序号。
printf("\t********** select ************\n");
printf("\t1: Preorder Traversal\n");    
printf("\t2: Iorder Traversal\n");
printf("\t3: Postorder traversal\n");
printf("\t4: PostTreeDepth,Node number,Leaf number\n");
printf("\t5: Level Depth\n");				//按层次遍历之前,先选择4,求出该树的结点数。
printf("\t0: Exit\n");
printf("\t*******************************\n");
fflush(stdin);
scanf("%c",&i);							//输入菜单序号(0-5)
switch (i-'0'){
case 1:	printf("Print Bin_tree Preorder: ");
Preorder(root);				//先序遍历
break;
case 2:	printf("Print Bin_Tree Inorder: ");
Inorder(root);				//中序遍历
break;
case 3:	printf("Print Bin_Tree Postorder: ");
Postorder(root);				//后序遍历
break;
case 4:
depth=TreeDepth(root);		//求树的深度及叶子数
printf("BinTree Depth=%d  BinTree Node number=%d",depth,NodeCount(root));
printf("  BinTree Leaf number=%d",countleaf(root));
break;
case 5:	printf("LevePrint Bin_Tree: ");
Levelorder(root);     //按层次遍历
break;
default: exit(1);
}
printf("\n");
} while(i!=0);
}
 
/********************************/
/*  基于先序遍历算法创建二叉树  */
/********************************/
//要求输入先序序列,其中加入虚结点"#"以示空指针的位置
BinTree CreateBinTree(void)
{
	char ch;
	BinTree T=NULL; 
	scanf("%c",&ch);
    if(ch=='#')return T;
    else
    {
        T= (BinTree)malloc(sizeof(BinTNode));//先创建一个结点,使用递归算法
        T->data=ch;
        T->lchild=CreateBinTree();//创建左子树
        T->rchild=CreateBinTree();//创建右子树
    }
	return T;
}


/********************************/
/*       先序遍历二叉树         */
/********************************/
void Preorder(BinTree T)
{	
	if(T==NULL)return ;
    else
    {
       printf("%c-->",T->data);
       Preorder(T->lchild);
       Preorder(T->rchild);
    }
}

/********************************/
/*       中序遍历二叉树         */
/********************************/
void Inorder(BinTree T)
{
	if(T==NULL)return ;
    else
    {
       Inorder(T->lchild);
	   printf("%c-->",T->data);
       Inorder(T->rchild);
    }


}

/********************************/
/*       后序遍历二叉树         */
/********************************/
void Postorder(BinTree T)
{
	if(T==NULL)return ;
    else
    {
       Postorder(T->lchild);
       Postorder(T->rchild);
	  printf("%c-->",T->data);
    }
}

/************************************************/
/*  采用后序遍历求二叉树的深度、结点数及叶子数  */
/************************************************/
//要求采用递归算法
int TreeDepth(BinTree T)
{
	int h1,h2;
	if(T==NULL)return 0;
	else
	{
		h1=TreeDepth(T->lchild);//后序遍历,先求左右子树的深度
		h2=TreeDepth(T->rchild);
		if(h1>h2)//进行比较,树的深度是左右子树深度的最大值加1
		{
			h1+=1;
		}
		else
		{
			h2+=1;
		}
	}
}

/**************************************************/
/*  利用"先进先出"(FIFO)队列,按层次遍历二叉树  */
/**************************************************/
/*队列的front指向第一个数据,rear指向最后一个数据的
后一位。队列最大长度为100*/
/*思路:将根节点放入队伍,再从队伍取出,读出结点的数
据,将左右子树的结点排入队伍,实现一层一层,从上至下,
从左到右遍历二叉树的目的
*/
void Levelorder(BinTree T)
{
	BinTree temp;
	SqQueue Q;
	Q.rear=Q.front=0;//建立一个空队伍
	if(T)
	{
		Q.base[Q.rear]=T;
		Q.rear=(Q.rear+1)%100;//入队操作,循环链表的长度是100
		while(Q.rear!=Q.front)
		{
			temp=Q.base[Q.front];
			printf("%c-->",temp->data);
			Q.front=(Q.front+1)%100;//出队操作
			if(temp->lchild)
			{
				Q.base[Q.rear]=temp->lchild;
				Q.rear=(Q.rear+1)%100;//左子树进入队伍
			}
			if(temp->rchild)
			{
				Q.base[Q.rear]=temp->rchild;
				Q.rear=(Q.rear+1)%100;//右子树进入队伍
			}
		}

	}
}
/********************************/
/*       数叶子节点个数         */
/********************************/
int countleaf(BinTree T)
{
	if(T==NULL){return 0;}
    if(T->lchild==NULL&&T->rchild==NULL)//判断是否是叶子结点,是的话返回1 
    {
        return 1;
    }
    else
		//不是叶子的结点的话继续向下层查找叶子结点,并将左右子树的叶子结点相加
	{
	return countleaf(T->lchild)+countleaf(T->rchild);
	}
}

/********************************/
/*       数总的节点个数         */
/********************************/
int NodeCount(BinTree T)
{
    if(T==NULL)return 0;
    else
        return NodeCount(T->lchild)+NodeCount(T->rchild)+1;//记得+1,加上根节点
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值