二叉树系列(建树,前序,中序,后序,中序非递归,深度,叶子数,节点数)

二叉树

                                         a

                                     /       \

                                 b            $

                            /         \     

                      c                  d

                   /    \               /       \  

                $      $            e            f

                                    /   \         /    \

                                 $     g      $       $

                                      /    \

                                     $    $

结点类型和指针

typedef char TElemType;
typedef  struct  BiTNode
{
	TElemType data;
	struct BiTNode  *lchild, *rchild;   //左右孩子指针
} BiTNode, *BiTree;


① 创建二叉树CreatBiTree()

char Vexch[15]={'a','b','c','$','$','d','e','$','g','$','$','f','$','$','$'};
int i=0;
//二叉树的创建
Status CreatBiTree(BiTree &T)
{
	if(Vexch[i++]=='$') T=NULL;
	else
	{
		T= new BiTNode;
		if(!T)  return 0;
		T->data=Vexch[i-1];//生成根节点
		CreatBiTree(T->lchild);//创建左子树
		CreatBiTree(T->rchild);//创建右子树
	}
	return 1;
}

建立二叉树时:判断 i 是否为空 ,那么指针指向空

                        建树建完本结点后,首先先建左子树,左子树碰到叶子后,才往右边建右子树


② 先序遍历二叉树 PreOrderTraverse()

//先序遍历二叉树
Status PreOrderTraverse(BiTree T,void( * visit)(TElemType))
{
	if(T)
	{
		visit(T->data);
		PreOrderTraverse(T->lchild,visit);
		PreOrderTraverse(T->rchild,visit);
	}
	return 1;
}

判断本结点是否为空,非空就输出本结点的data(根),再输出左子树(左),再输出右子树(右):(根>左>右)


③ 中序遍历二叉树 InOrderTraverse()

//中序遍历二叉树
Status InOrderTraverse(BiTree T,void( * visit)(TElemType))
{
	if(T)
	{
		InOrderTraverse(T->lchild,visit);
		visit(T->data);
		InOrderTraverse(T->rchild,visit);
	}
	return 1;
}

判断本结点是否为空,非空先输出左子树(左),再输出本结点data(根),再输出右子树(右):(左>根>右)


④ 后序遍历二叉树 PostOrderTraverse()

//后序遍历二叉树
Status PostOrderTraverse(BiTree T,void( * visit)(TElemType))
{
	if(T)
	{
		PostOrderTraverse(T->lchild,visit);
		PostOrderTraverse(T->rchild,visit);
		visit(T->data);
	}
	return 1;
}
判断本节点是否为空,非空先输出左子树(左),再输出右子树(右),再输出本节点data(根):(左>右>根)

⑤ 释放子树 Destory()

//释放T所指子树,该函数在析构函数中被调用
void Destory(BiTree T)
{
	if(T)
	{
		Destory(T->lchild);
		Destory(T->rchild);
		delete T;
	}
}

用后序遍历,释放子树。


⑥ 中序遍历非递归实现 InOrderNotRescure()

//中序遍历二叉树的非递归实现,visit为遍历操作函数
void InOrderNotRescure(BiTree T,void( * visit)(TElemType))
{
	stack<BiTree> S;
	while(!S.empty() || T!=NULL )
	{
		if(T!=NULL)
		{
			S.push(T);
			T=T->lchild;
		}
		else 
		{
			T=S.top();
			visit(T->data);
			S.pop();
			T=T->rchild;
		}
	}//end of while
}
.利用栈,先将根节点存到栈里(暂不输出),然后往左子树探,探到最左后,没有左边之后(弹出栈,输出值),再往右边探。


⑦ 计算二叉树结点 NodesCount()

//计算二叉树结点
int NodesCount(BiTree T)
{
	if(T == NULL) return 0;
	else
		return NodesCount(T->lchild)+NodesCount(T->rchild)+1;
}
用递归,每一个函数往左边和右边(顺序无关),两个方向探索,然后每探索成功一次,说明有一个结点,+1。出口为结点为空

⑧ 计算二叉树深度 Deepth()

//计算二叉树深度
int Deepth(BiTree T)
{
	if(T == NULL) return 0;
	else
	{
		int left= Deepth(T->lchild);
		int right = Deepth(T->rchild);
		if(left > right) 
			return left+1;
		else 
			return right+1;
	}
}
用递归,向左右探索(顺序无关),返回的值是二叉树的深度,分治思想,在左边和右边的子树那个深度大,那么就选那个深度大的+1 。出口为结点为空。


⑨ 计算二叉树叶子数目 LeafCount()

//计算二叉树的叶子数目
int LeafCount(BiTree T)
{
	if(T == NULL) 
		return 0;
	else if(T->lchild == NULL && T->rchild==NULL)
		return 1;
	else
		return LeafCount(T->lchild)+LeafCount(T->rchild);
}
递归,和探索结点一样,左右探索(顺序无关),结点左右子树皆为空,才是叶子。出口两个,结点为空返回0,结点的左右子树为空返回1。

(为什么要结点为空返回0?因为A的左子树这个情况的时候,就要返回0,B的情况返回1) 

        A

      /    \

    $      B

          /    \

       $        $


⑩ 主函数main()和visit()函数

void visit (char e)
{
	printf("%5c",e);
}
int main()
{
	BiTree T;
	printf("1.建立二叉树\n");
	printf("二叉树:");CreatBiTree(T);
	printf("\n2.前序遍历二叉树\n");
	PreOrderTraverse(T,visit);
	printf("\n3.中序遍历二叉树\n");
	InOrderTraverse(T,visit);
	printf("\n4.后序遍历二叉树\n");
	PostOrderTraverse(T,visit);
	printf("\n5.非递归中序遍历二叉树\n");
	InOrderNotRescure(T,visit);
	printf("\n6.计算二叉树的深度\n");
	printf("树的深度为:%d\n",Deepth(T));
	printf("\n7.计算二叉树的叶子树\n");
	printf("树的叶子树为:%d\n",LeafCount(T));
	printf("\n8.计算二叉树的节点数\n");
	printf("树的节点数为:%d\n",NodesCount(T));
	return 0;
}


结果:




  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值